3

当我在此代码段上运行反引号 (`) 命令时:

Get-WmiObject win32_service | Where-Object { $_.pathname -notlike "C:\windows\*" -and $_.startmode -eq "auto" -and $_.startname -eq "localsystem"} | Select-Object displayname, `
pathname, startmode, startname | Format-List | Out-Host

我得到一些错误。这些错误是什么?

首先,通过在第一行按 F8,我得到这个:

不完整的字符串标记。+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : IncompleteString

目标运行代码段并假设 PC 将自动跳到下一行,因为它有 ` 字符

其次,当我只突出显示第一行时,通过单击行号的左侧,我现在得到了这个:

在行:1 字符:170

  • ... to" -and $_.startname -eq "localsystem"}|Select-Object displayname, `
  •                                                                    ~ Missing expression after ',' > in pipeline element.
    
    • CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    • FullyQualifiedErrorId : MissingExpression

目标运行代码段并假设 PC 将自动跳到下一行,因为它有 ` 字符

但是,当我按 F5 时,它就像一个魅力。请原谅我对 PowerShell 的无知,但我在这里做错了什么?

附加信息:这是我的 powershell 信息:

  • 名称:Windows PowerShell ISE 主机
  • 版本:5.1
4

2 回答 2

4

您的错误来自 PowerShell ISE 的功能。

First you're trying to use F8 which is "Run Selection", on the first line, with no selection made. That will implicitly select all the characters of the first line, then try to run that.

When you do so, you get the incomplete string token error, and that's because the parser has encountered the lone backtick ` (the escape character), with no character following it. That's because the newline at the end of the line, which the backtick is usually escaping (that's how it works as a line continuation character), is missing, since the single line selection didn't include it.

Second, when I highlight just the first line, by clicking to the left of the line numbers

Now in this case you'll notice that your selection has placed the cursor at the beginning of the next line. That means this selection does include the newline, and so you now have a complete string token.

Your error is that you've now ended your command with a comma, as though you're going to pass more parameters, and then nothing comes after (the rest of the parameters were not included in your selection).


The root of the issue is that the commands in ISE that deal with running a selection, are doing exactly that, so if you want them to include things that are on the next line, you must include them in the selection too.


As a side note, I might recommend that you look for code elements which let you naturally use line breaks, such as the pipe | character, operators, and scriptblock braces {}.

Get-WmiObject win32_service | 
    Where-Object { 
        $_.pathname -notlike "C:\windows\*" -and 
        $_.startmode -eq "auto" -and 
        $_.startname -eq "localsystem"
    } | 
    Select-Object displayname, pathname, startmode, startname | 
    Format-List | 
    Out-Host

This doesn't solve your selection problem, but it's nicer to read in my opinion, and doesn't require the awkward backtick.

于 2021-05-03T03:11:44.723 回答
2

跟进@Santiagos 链接评论:

这称为语句终止。使用 Powershell 时,有 2 个语句终止符

  1. 分号 -;
  2. 换行符(有时)

换行的规则有时只是由于某些用户使用命令的性质。基本上意味着如果前面的文本在语法上是完整的语句,则新行被认为是语句终止。因此,如果它不完整,则换行符将被视为空格。

快速示例:

PS C:\Users\Abraham> 3 +
>> 4
7

当我添加+运算符时,它期待另一个参数,这就是它没有出错的原因。

在您的情况下,我将假设错误来自 powershells Tokenizer(词法分析器)在解析您的命令时,因为它会将您的反引号读取为逗号的转义字符(假设它是完整的 - 因此是语句终止符- 读取下一行作为换行符而不是空格);在我看来(如果我错了,有人纠正我),我认为这是一个错误,它是一个False-Positive

Backtik (`) 也称为转义字符,可以扩展不可扩展的行。如果行中的最后一个字符是反引号,则换行符将被视为空格而不是“换行符”。

所以你不需要那个反引号,因为你的逗号 ( ,) 告诉 powershell 后面还有更多内容,我们参考第 2 段的语法不完整。

总而言之: 这是 powershells end(:

PS - 很抱歉这篇文章很长,因为第一部分并不是真正需要回答你的问题;只是一些可以帮助您了解它如何组合在一起的信息。

编辑:

没有看到F8这里的罪魁祸首哈哈感谢@briantist 指出来。错误不在 Powershell 端。无视这篇文章(:

于 2021-05-03T02:59:31.610 回答