如何在 PowerShell 中的一行上运行多个命令?

Dav*_*vid 429 windows powershell command-line

在 cmd 提示符下,您可以在一行上运行两个命令,如下所示:

ipconfig /release & ipconfig /renew
Run Code Online (Sandbox Code Playgroud)

当我在 PowerShell 中运行此命令时,我得到:

Ampersand not allowed. The `&` operator is reserved for future use
Run Code Online (Sandbox Code Playgroud)

PowerShell 是否有允许我&在 cmd 提示符下快速生成等效项的运算符?

在一行中运行两个命令的任何方法都可以。我知道我可以制作一个脚本,但我正在寻找更多的东西。

Squ*_*ezy 607

在 PowerShell 中使用分号链接命令:

ipconfig /release; ipconfig /renew
Run Code Online (Sandbox Code Playgroud)

  • 虽然有很大的不同 - “;” 即使第一个命令失败,也会运行第二个命令。 (63认同)
  • 这将按顺序运行它们,就像 cmd.exe 中的 & 运算符一样。 (27认同)
  • 它们是并行运行还是顺序运行? (13认同)
  • 如上所述,这也是cmd.exe中&的行为。 (13认同)
  • @Rafi 是的,尝试 {Command-One -ea Stop} 抓住 {Command-Tw​​o} (11认同)
  • 有没有办法让第二个命令只在第一个失败时运行? (7认同)
  • 直接使用 throw 关键字( throw 是关键字是这里的重要部分)和运行抛出错误的脚本是有区别的。<powershell -c "抛出'错误'"; write-host " no error"> 将按顺序运行这两个命令。即使第一个命令引发终止错误,也会发生这种情况。 (4认同)

Dav*_*e_J 36

分号将按照前面的答案链接命令,尽管与&MS-DOS 样式命令解释器中的操作符的行为存在关键差异。

在命令解释器中,当读取该行时会发生变量替换。这允许一些巧妙的可能性,例如在没有过渡的情况下交换变量:

set a=1
set b=2
set a=%b% & set b=%a%
echo %a%
echo %b%
Run Code Online (Sandbox Code Playgroud)

会导致:

2
1
Run Code Online (Sandbox Code Playgroud)

据我所知,无法在 PowerShell 中复制此行为。有些人可能会争辩说这是一件好事。

事实上,在 PowerShell 中有一种方法可以做到这一点:

$b, $a = $a, $b
Run Code Online (Sandbox Code Playgroud)

这将导致变量值的单行交换。


Sim*_*onS 24

在 PowerShell 7 中,我们Pipeline chain operators允许您向连续的单行命令添加一些条件元素

运营商是:

  • && 仅当第一个命令成功时,才会运行第二个命令。
  • || 这将仅在第一个命令失败时运行第二个命令。

例子:

PS Z:\Powershell-Scripts> Write-Host "This will succeed" && Write-Host "So this will run too"
This will succeed
So this will run too

PS Z:\Powershell-Scripts> Write-Error "This is an error" && Write-Host "So this shouldn't run"
Write-Error "This is an error" && Write-Host "So this shouldn't run": This is an error

PS Z:\Powershell-Scripts> Write-Host "This will succeed" || Write-Host "This won't run"
This will succeed

PS Z:\Powershell-Scripts> Write-Error "This is an error" || Write-Host "That's why this runs"
Write-Error "This is an error" || Write-Host "That's why this runs": This is an error
That's why this runs
Run Code Online (Sandbox Code Playgroud)

当然,您可以像x && y || z等一样将它们链接在一起。

这也适用于旧的类似 cmd 的命令,例如 ipconfig

PS Z:\Powershell-Scripts> ipconfig && Write-Error "abc" || ipconfig


Windows-IP-Konfiguration


Ethernet-Adapter Ethernet:

   Verbindungsspezifisches DNS-Suffix: xxx
   Verbindungslokale IPv6-Adresse  . : xxx
   IPv4-Adresse  . . . . . . . . . . : xxx
   Subnetzmaske  . . . . . . . . . . : 255.255.255.0
   Standardgateway . . . . . . . . . : xxx
ipconfig && Write-Error "abc" || ipconfig: abc

Windows-IP-Konfiguration


Ethernet-Adapter Ethernet:

   Verbindungsspezifisches DNS-Suffix: xxx
   Verbindungslokale IPv6-Adresse  . : xxx
   IPv4-Adresse  . . . . . . . . . . : xxx
   Subnetzmaske  . . . . . . . . . . : 255.255.255.0
   Standardgateway . . . . . . . . . : xxx
Run Code Online (Sandbox Code Playgroud)

这些运算符使用 $? 和 $LASTEXITCODE 变量来确定管道是否失败。这允许您将它们与本机命令一起使用,而不仅仅是与 cmdlet 或函数一起使用。

来源:https : //docs.microsoft.com/en-us/powershell/scripting/whats-new/what-s-new-in-powershell-70?view=powershell-7


小智 14

对于PowerShell 5(在可预见的将来Windows机器上默认安装),您当然可以使用分号来分隔语句,但即使有一条语句失败,所有语句都会默认执行。就我个人而言,我更喜欢运行一些东西,这样如果一件事失败了,整个生产线都会在 REPL 中停止,我想很多其他人也会这样做。

$ErrorActionPreference允许您控制当语句失败但为非终止错误(这是大多数错误,包括命令未找到错误)时发生的行为。您可以设置此变量,$ErrorActionPreference="Stop"以便&&在该变量的范围内模拟 Bash 和 PowerShell 7 中的行为。

$ErrorActionPreference="Stop"
# Line break
fakeCommand; echo "Here"
Run Code Online (Sandbox Code Playgroud)

我很难找到这种行为的精确文档,但这个变量似乎是动态范围的,因此如果您不想全局设置它,您可以暂时在块中覆盖它。

Invoke-Command -ScriptBlock {$ErrorActionPreference="Stop"; fakeCommand; echo "Here"}
Run Code Online (Sandbox Code Playgroud)

最后,如果您想要可重用的东西,您可以使用这个高阶函数。

function Run-Block-With-Error($block) {
    $ErrorActionPreference="Stop"
    Invoke-Command -ScriptBlock $block
}
Run Code Online (Sandbox Code Playgroud)

然后使用如下。

Run-Block-With-Error {fakeCommand; echo "Here"}
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的示例中,“Here”未打印,因为fakeCommand它不是真正的命令,因此失败。

我已经针对 PowerShell 5 和 7 测试了此解决方案中提供的代码,它应该是完全可移植的,至少在 Windows 上是这样。虽然 PowerShell 7 在不同平台上应该非常相似,但我没有在 Linux 或 MacOS 上测试这些命令。