【问题标题】:Can I get "&&" or "-and" to work in PowerShell?我可以让“&&”或“-and”在 PowerShell 中工作吗?
【发布时间】:2010-10-08 11:52:48
【问题描述】:

众所周知,&& 在 Google 搜索中很难搜索,但我发现最好的是 this article,它表示要使用 -and

不幸的是,它没有提供更多信息,而且我不知道我应该用 -and 做什么(同样,这是一个众所周知的难搜索)。

我尝试使用它的上下文是“执行 cmd1,如果成功,则执行 cmd2”,基本上是这样的:

csc /t:exe /out:a.exe SomeFile.cs && a.exe

如果您只想在一行上运行多个命令,并且不在乎第一个命令是否失败,您可以使用 ; 就我的大多数目的而言,这很好。

例如:kill -n myapp; ./myapp.exe

【问题讨论】:

  • PowerShell 有 -and 和 -or 逻辑运算符。操作员是否没有按照您期望的方式工作?如果是这样,您可以在此处发布表达式。
  • 看到这个问题,它做你想做的事:stackoverflow.com/questions/1917271/…
  • 关于需要对带有文字(和重要)符号的查询执行网络搜索:SymbolHound 对此很有用。以下是与该问题相关的一些示例:powershell &&; powershell -and。如果你使用DuckDuckGo,你可以通过!sym搜索SymbolHound。
  • 2019 年 6 月更新:PowerShell 团队正在实施 &&||!在GitHub PR称重
  • 在 PowerShell 7 中实现了 &&||。他们被称为“管道链运营商”。 docs.microsoft.com/en-us/powershell/module/…

标签: syntax powershell


【解决方案1】:

只需安装 PowerShell 7(go here,然后滚动并展开资产部分)。 This release已经实现了管道链算子。

【讨论】:

    【解决方案2】:

    如果您的命令在 cmd.exe 中可用(类似 python ./script.py,但不是类似 ii . 的 PowerShell 命令(这意味着通过 Windows Explorer 打开当前目录)),您可以在 PowerShell 中运行 cmd.exe .语法是这样的:

    cmd /c "command1 && command2"
    

    这里,&&in this question 描述的 cmd 语法提供。

    【讨论】:

    • 很好,升级到 cmd 以访问它的附加功能。
    【解决方案3】:

    我认为一个简单的if 语句可以做到这一点。一旦我看到 mkelement0 的响应,最后的退出状态存储在 $? 中,我将以下内容放在一起:

    # Set the first command to a variable
    $a=somecommand
    
    # Temporary variable to store exit status of the last command (since we can't write to "$?")
    $test=$?
    
    # Run the test
    if ($test=$true) { 2nd-command }
    

    因此,对于 OP 的示例,它将是:

    a=(csc /t:exe /out:a.exe SomeFile.cs); $test = $?; if ($test=$true) { a.exe }
    

    【讨论】:

      【解决方案4】:

      我们可以试试这个命令,而不是使用 && 方法:

      try {hostname; if ($lastexitcode -eq 0) {ipconfig /all | findstr /i bios}} catch {echo err} finally {}
      

      【讨论】:

      • 不需要try / catch,因为它只在terminating错误时需要,外部实用程序如hostnameipconfigfindstr 无法触发。仅当您想知道由外部实用程序设置的特定退出代码时才需要检查 $LASTEXITCODE - 抽象的成功或失败反映在 $? 中,就像原生 cmdlet 一样。
      • 我认为@Cyber​​iron 是在正确的轨道上。我认为 Unix 中的 && 很像 try/catch,因为它不需要你将后续命令包装在一个新块中(即}),当你短路以后的命令(跳过它们)。我认为if (!?) { throw "last command failed" } 时抛出的AmpAmp 函数/过滤器将是将&& 移植到PowerShell 的非常有用的替代品。 用法csc /t:exe /out:a.exe SomeFile.cs; AmpAmp; a.exe
      【解决方案5】:

      用途:

      if (start-process filename1.exe) {} else {start-process filename2.exe}
      

      它比“&&”长一点,但它无需编写脚本就能完成同样的事情,而且不太难记。

      【讨论】:

      • Start-Process 通常是用于调用命令行实用程序的错误工具。具体来说,这里使用的Start-Process 在新的控制台窗口中异步运行filename1.exe 并返回nothing,在布尔上下文中计算为$false。即使您省略了Start-Process(这是您应该直接调用命令行实用程序的方式),该方法也会失败,因为条件的结果取决于实用程序是否产生任何标准输出输出,这没有保证关系不管成功与否。
      【解决方案6】:

      我在 PowerShell 中尝试了以下命令序列:

      第一次测试

      PS C:\> $MyVar = "C:\MyTxt.txt"
      PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
      True
      

      ($MyVar -ne $null) 返回 true(Get-Content $MyVar) 也返回 true

      第二次测试

      PS C:\> $MyVar = $null
      PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
      False
      

      ($MyVar -ne $null) 返回 false 到目前为止,我必须假设 (Get-Content $MyVar) 也返回 false

      第三个测试证明第二个条件甚至没有被分析。

      PS C:\> ($MyVar -ne $null) -and (Get-Content "C:\MyTxt.txt")
      False
      

      ($MyVar -ne $null) 返回 false 并通过在整个命令上返回 false 证明第二个条件 (Get-Content "C:\MyTxt.txt") 从未运行。

      【讨论】:

      • 你说得对!这表现为 && 运算符。即使是右侧的 $() 也不会让评估这个!
      【解决方案7】:

      非常老的问题,但对于新手:也许问题正在寻找的 PowerShell 版本(类似但不等效)是使用-and,如下所示:

      (build_command) -and (run_tests_command)

      【讨论】:

      • 这对于您的用例可能没问题,但它的行为不像&&,因为它忽略了build_command 的退出代码。
      • 这绝对不是正确的做法。即使第一个命令失败,它也会运行第二个命令。
      • 这是完全错误的。 ; 相当于 cmd 中的 & 和 bash 中的 ;。绝对和cmd里的&&不一样
      • 它还为两个进程静音 STDOUT 和 STDERR。
      【解决方案8】:

      在CMD中,'&&'表示“执行命令1,如果成功则执行命令2”。我用它来做以下事情:

      build && run_tests
      

      在 PowerShell 中,您可以做的最接近的事情是:

      (build) -and (run_tests)
      

      它具有相同的逻辑,但是命令的输出文本丢失了。不过,也许它对你来说已经足够了。

      如果您在脚本中执行此操作,最好将语句分开,如下所示:

      build
      if ($?) {
          run_tests
      }
      

      2019/11/27&&operator 现在可用于PowerShell 7 Preview 5+

      PS > echo "Hello!" && echo "World!"
      Hello!
      World!
      
      

      【讨论】:

      • RE:“他们会删除可笑” - 我不喜欢将 PowerShell 视为“删除了愚蠢部分的 CMD”。 is.gd/k92B
      • 我不喜欢将 PowerShell 视为“删除了愚蠢部分的 CMD”。我喜欢将其视为“没有任何有用位的 Bash”。
      • 你也可以在命令行上做build ; if ($?) { run_tests }
      • 在学习 PowerShell 时真正感到沮丧的最快方法是首先认为它只是扩展的 CMD 或 bash。它有一个完全不同的模型,尤其是在输入、输出、管道和结果方面。从一个好的教程或概述开始,不要太努力地让其他 shell 的语法工作。你必须按照自己的条件来看待它。
      • 按照 PowerShell 本身的条件,我如何运行一个命令,然后,只有当该命令成功时,才运行另一个命令?我认为这不会在 PowerShell 上强加 bash 想法。这是基本的外壳功能。到目前为止,我见过的最好的是build ; if ($?) { run_tests },我将从现在开始使用它。希望 PowerShell 团队增加对&& 的支持!
      【解决方案9】:

      一个详细的等价物是结合$LASTEXITCODE-eq 0

      msbuild.exe args; if ($LASTEXITCODE -eq 0) { echo 'it built'; } else { echo 'it failed'; }
      

      我不确定为什么 if ($?) 对我不起作用,但这个起作用了。

      【讨论】:

      • 检查$LASTEXITCODE 确实是最可靠的方法,因为不幸的是,$? 可以通过2> 重定向产生误报;见this answer
      【解决方案10】:

      试试这个:

      $errorActionPreference='Stop'; csc /t:exe /out:a.exe SomeFile.cs; a.exe
      

      【讨论】:

      • 注意:如果第一个命令失败,第二个命令仍然会运行。
      • 首选项变量$ErrorActionPreference 仅控制如何处理cmdlet 报告的非终止错误; csca.exe 等外部实用程序从不报告此类错误(它们仅在 $?(成功标志)和 $LASTEXITCODE(报告的特定退出代码)中反映其退出状态),因此您的命令行相当于 无条件执行两个命令(相当于cmdcsc /t:exe /out:a.exe SomeFile.cs & a.exe
      【解决方案11】:

      && 和 ||在要实施的事情列表中(仍然是),但没有作为下一个最有用的添加内容弹出。原因是我们有 -AND 和 -OR。 如果您认为这很重要,请在 Connect 上提出建议,我们会考虑将其用于 V3。

      【讨论】:

      • 我在 Connect 上注册,并提名自己为 powershell,但我不知道如何提出建议。 Connect 网站非常复杂且令人困惑 :-(
      • 我找不到预先存在的请求,所以我提出了一个:connect.microsoft.com/PowerShell/feedback/details/778798/…
      • 你知道,问题仍然是如何写一个等价的,如果你添加一个 using -AND的例子,你的答案会更有用>
      • 这很重要,因为它是一种基本的流控制工具,几乎永远用于比 Windows 更早的系统。这就是 linux 和 windows 之间的另一个重大差异。
      • 我希望 Jeffrey Snover 正在倾听,这个 SO 应该是现在实施它的充分理由。时间太长了,现在 PowerShell 开始在一些地方弹出,比如 VSCode 将其用作 Windows 中的默认终端。这是没有 && 的全部痛苦,-and 吃掉了输出,根本不等价。
      【解决方案12】:

      这取决于上下文,但这里有一个“-and”的例子:

      get-childitem | where-object { $_.Name.StartsWith("f") -and $_.Length -gt 10kb }
      

      这样就可以在文件名以“f”开头的目录中获取所有大于 10kb 的文件。

      【讨论】:

      • 这不是原始问题的答案,这是关于执行多个命令的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-11
      相关资源
      最近更新 更多