ChatGPT解决这个技术问题 Extra ChatGPT

如何输入多行命令

是否可以将 PowerShell 命令行拆分为多行?

在 Visual Basic 中,我可以使用下划线 (_) 继续下一行中的命令。

Bruce Payette 的 PowerShell in Action 很好地涵盖了“为什么不使用反斜杠”的问题;好书。 Bruce 对编程语言的历史有着广泛的了解。期待这本书的V2。
抱歉,如果偏离主题,但如果您要使用 sh 命令提交脚本,则 bash 约定适用,因此您可以使用反斜杠。在这种情况下,您的脚本也应该有 unix 风格的结尾。
只需使用 ` 字符在多行上分隔命令

J
Joey

您可以使用空格后跟重音(反引号):

Get-ChildItem -Recurse `
  -Filter *.jpg `
  | Select LastWriteTime

但是,只有在上述情况下才需要这样做。通常,当命令在该点在语法上无法完成时,您会自动续行。这包括启动一个新的管道元素:

Get-ChildItem |
  Select Name,Length

将毫无问题地工作,因为在 | 之后,由于缺少另一个管道元素,该命令无法完成。同样打开花括号或任何其他类型的括号将允许直接续行:

$x=1..5
$x[
  0,3
] | % {
  "Number: $_"
}

| 类似,逗号也可以在某些情况下使用:

1,
2

但请记住,与 JavaScript 的 Automatic Semicolon Insertion 类似,有些东西也同样被破坏,因为换行发生在 前面有一个有效语句的位置:

return
  5

不管用。

最后,字符串(所有种类)也可能超出单行:

'Foo
bar'

然后,它们在字符串中包含换行符。


并且不要忘记提及其他一些标记也充当行连续符,例如 |{
@Keith:谢谢,我把它包括在内。这些可能太明显了,无法提及;-)
不,最好将这些其他字符记录下来以供将来参考。
@JackDouglas:您可以在左括号之后直接换行,但显然不能在运算符之前的表达式中。话虽如此,我认为这是对语法的疏忽。
显然,续行在 ISE 命令窗格中不起作用。
P
Peter Mortensen

我刚刚发现,反勾号和换行符之间不能有任何字符。即使是空格也会导致命令不起作用。


虽然这在技术上不是问题的答案,但 +1 因为这是绝对必要的。我刚刚发现这一点很困难,并且肯定会尽可能避免在未来的开发中出现倒钩。
因此,基本上没有可靠的方法来打破 Powershell 中的长线。难怪我到处都能看到那些2-screen-wide powershell scripts。 #摇摇头
我也在为此苦苦挣扎...您可以在反引号之前插入内联注释以包含注释,如下所示: Some-Command ` -arg1 <# explain arg 1 #> ` -arg2 <# explain arg 2 #>
呃。这使得 PowerShell 代码在文档或网站中发布变得不必要地困难,因为担心如果使用 Shift+Enter,该命令会被人读错,或者在使用反勾号时在 ISE 的命令行中解析错误。
技术说明 - 这是因为反引号本身不是续行运算符;它实际上是一个 escape 字符,用于“转义”行尾的换行符。如果您在反引号后输入一个空格,它将转义该空格而不是换行符。在 Natural Line Continuations in PowerShell 进一步阅读
J
Jay Bazuzi

在大多数类似 C 的语言中,我故意将大括号放在我认为它们使代码最容易阅读的地方。

PowerShell 的解析器会识别出明显不完整的语句,并查看下一行。例如,想象一个带有可选脚本块参数的 cmdlet:

Get-Foo { ............ }

如果脚本块很长,您可能需要编写:

Get-Foo
    {
        ...............
        ...............
        ...............
    }

但这不起作用:解析器将看到两个语句。第一个是 Get-Foo,第二个是脚本块。相反,我写道:

Get-Foo {
        ...............
        ...............
        ...............
    }

我可以使用续行字符 (`),但这会导致代码难以阅读,并且会引起错误。

因为这种情况需要左大括号在前一行,所以我到处都遵循这个模式:

if (condition) {
        .....
    }

请注意,如果语句需要语言语法中的脚本块,因此解析器将在下一行查找脚本块,但为了保持一致性,我将左大括号保留在同一行。

同样,在长管道的情况下,我在管道字符 (|) 之后中断:

$project.Items | 
        ? { $_.Key -eq "ProjectFile" } | 
        % { $_.Value } | 
        % { $_.EvaluatedInclude } |
        % {
            .........
        }

那么 ifforeachtry 是如何工作的呢?他们允许下一行的脚本块......这意味着它是可能的
@Nacht:来自生锈的记忆:根据语言语法,需要脚本块的语句将解析换行符以找到一个。任何人都可以确认吗?
@Nacht:“但这不起作用”指的是其他参数是可选的情况,这是大多数情况。
啊,我明白你的意思了。所以“if”和“foreach”实际上不是 cmdlet - 它们实际上是语法的一部分,因此迫使它看过去到下一行。那么有没有办法让用户定义的函数从下一行读取脚本块?我想你上面的答案完全回答了这个问题。
C
Community

要扩展 cristobalito's answer

我假设您在命令行上谈论 - 如果它在脚本中,那么换行符 > 充当命令分隔符。在命令行上,使用分号 ';'

例如:

在命令行上签署 PowerShell 脚本。没有换行符。

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}

不是问题的答案,但您的答案回答了我的问题。 :)
这很有趣,但这与 OP 所要求的相反。 OP 想要将单个命令拆分为多行;您解释了如何将多个命令组合到一行中。
P
Peter Mortensen

在 PowerShell 和 PowerShell ISE 中,还可以在每行的末尾使用 Shift + Enter 进行多行编辑(而不是标准的反引号 `)。


这是编辑多行 here-strings 的一个很好的技巧,如果您不知道 SHIFT-ENTER 技巧,否则编辑起来会很糟糕。
我相信只有在使用 PSReadLine 模块或等效模块时,PowerShell 的控制台版本才会出现这种情况。在标准的 Windows 控制台输入函数中,EnterShift+Enter 在功能上是等效的。
@Bill_Stewart 是的,它可以在没有 PSReadline 的 ISE 控制台中工作,但不能在控制台主机中工作。
澄清一下:1) PSReadline 模块在控制台主机中工作(不是 ISE)。 2) Shift+Enter 仅在使用 PSReadline 时在控制台主机中工作。 3) Shift+Enter 一直在 ISE 中工作。 4) 如果使用不带 PSReadline 的控制台主机,Shift+Enter 在功能上等同于按 Enter
这是正确的答案,被接受并有 400 票赞成的答案非常混乱和无用!
J
Jian Huang

只需在此处添加一个角落案例。它可能会为您节省 5 分钟。如果你使用一个动作链,你需要放“.”。在行尾,留一个空格,后跟“`”(反引号)。我发现这很困难。

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")

非常感谢!尝试了一段时间未能成功实现这一目标..
只要将点放在前一行上,似乎就可以在没有空格和反引号的情况下工作,即使在它之后和后续方法调用之前有空格也是如此。甚至评论也有效,例如 Replace("HELLO", "Hello"). # comment here
N
Nissa

如果您尝试将字符串分成多行,则可以使用“+”。例如:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

看起来就像:

$header = "Make,ComputerName,Model,Windows Version"

J
JanRK

我开始做

if ($true) {
"you can write multiple lines here, and the command doesn't run untill you close the bracket"

"like this"
}

最近发现我可以

&{
get-date
"more stuff"
}

M
Mariusz Jamro

只需使用 ` 字符来分隔多行命令


c
cristobalito

我假设您在命令行上谈论 - 如果它在脚本中,那么换行符充当命令分隔符。

在命令行上,使用分号 ';'


M
Moslem Shahsavan

使用分号;分隔命令在任何反斜杠 \ 上替换双反斜杠 \\。使用 "' 传递安全地址以切换命令,如 "'PATH'"。

此 ps1 命令安装语言环境 pfx 证书。

powershell -Command "$pfxPassword = ConvertTo-SecureString -String "12345678" -Force -AsPlainText ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\My -Password $pfxPassword ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\Root -Password $pfxPassword"

n
ninMonkey

这是一个旧帖子,所以这是现代方法。

如果您使用的不是旧版 Powershell,最简洁的续行方式是 行首 处的 pipe

https://i.stack.imgur.com/pZMVu.png

注意:该命令不会因注释掉某些行而中断。这在命令行上很棒。

> Get-ChildItem -path 'c:\' -Depth 1                 
    | Sort-Object LastWriteTime                       
    # | Sort-Object Length -Descending                   
    | Select-Object -First 3 -Skip 3                   
    | Foreach-Object {                                 
      $_.Name, $_.Length | Join-String -Separator ' = '                                                       
    }                                                  

输出:

explorer.exe = 4826160                                 
procexp.old.exe = 2925760                              
RtlExUpd.dll = 2839488                                 

Windows Powershell(版本 < 6)

不幸的是 windows powershell 不支持它。上面链接了一堆替代方案。您可以完全删除反引号:2017/07/bye-bye-backtick-natural-line


j
js2010

有很多方法可以在 powershell 中继续一行,使用管道、括号、括号、运算符、点,甚至使用逗号。这是一篇关于它的博客:https://get-powershellblog.blogspot.com/2017/07/bye-bye-backtick-natural-line.html

您也可以在 foreach 和 if 等语句之后继续。


一篇长而有趣的文章。除了使用反引号转义换行符之外,还可以使用数组 splatting(即使 @ splat 运算符似乎不是必需的)。例如:$params = @( '-v', '-X', 'GET'); curl $params http://example.org。不是 '-X GET',而是需要两个单独的元素。并且不要调用变量 $args,它是保留的。
或者只是一个逗号继续。
是的,实际上不需要喷溅,但引号是:curl '-v', '-X', 'GET', 'http://example.org'。这篇文章的建议是使用带有 splatting 的变量来提高可读性。顺便说一句:如果写在一行上并且如果你删除了参数之间的空格,那么它会突然中断吗? curl '-v','-X','GET','http://example.org' - curl: option -v,-X,GET,http://example.org: is unknown。任何参数之间的单个空格使其再次工作。
M
Mike
$scriptBlock = [Scriptblock]::Create(@'
  echo 'before'
  ipconfig /all
  echo 'after'
'@)

Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

source
don't use backquote


J
Johannes

在 Windows 终端(powershell 配置文件)中,我只需单击 Shift-Enter 即可。

PS C:\xxx2021> Get-ChildItem -Include *remote* -Recurse |
>> Sort-Object -Property LastWriteTime -Descending  |
>> Select-Object LastWriteTime, Name -First 25

LastWriteTime        Name
-------------        ----
12/5/2021 5:04:02 PM remote-control-car-BatteryPack-Number-2021-12-03.pdf

PS C:\xxx2021>enter code here

如果默认未设置,则为函数 addLine -> Set-PSReadLineKeyHandler -Chord 'shift+enter' -Function AddLine