我能否在PowerShell中使用"&&"或"-and"?

301

注意: 该问题最初是在2009年提出的,当时powershell不支持&&运算符。 根据Jay的答案,在2019年,微软在Powershell 7中添加了对&&||的支持。 https://dev59.com/cHRB5IYBdhLWcg3wpYmo#564092


原始问题

&&在Google搜索上非常难以搜索到,但我找到的最好的方法是这篇文章,它说要使用-and

不幸的是,它没有提供更多信息,而且我找不到我应该如何使用-and(同样是一个非常难以搜索的东西)。

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

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

如果您只想在一行上运行多个命令,并且不关心第一个命令是否失败,您可以使用分号;。对于我大部分的目的而言,这样做就可以了。
例如:kill -n myapp; ./myapp.exe

PowerShell有-and和-or逻辑运算符。 如果这些运算符没有按照您的预期工作,您可以在此处发布表达式。 - Mohit Chakraborty
1
关于需要执行带有文字(且重要)符号的查询的需求:SymbolHound 对此非常有用。以下是一些与问题相关的示例:powershell &&; powershell -and。如果您使用 DuckDuckGo,您可以通过 !sym 搜索 SymbolHound。 - nisavid
2019年更新:我已将此作为功能请求添加到PowerShell中:https://github.com/PowerShell/PowerShell/issues/8570 - mikemaccana
4
2019年6月更新:PowerShell团队正在实现“&&”和“||”!请在GitHub PR上发表您的意见! - pilau
2
从PowerShell 7开始,实现了&&||。它们被称为“管道链运算符”。https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pipeline_chain_operators?view=powershell-7 - Tomoyuki Aota
显示剩余3条评论
14个回答

315
在CMD中,'&&'的意思是“执行命令1,如果成功则执行命令2”。我经常用它来做一些类似的事情:
build && run_tests

在PowerShell中,你可以做到最接近的是:

(build) -and (run_tests)

这里的逻辑与之前相同,但命令的输出文本会丢失。但是也许对您来说已经足够好了。

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

build
if ($?) {
    run_tests
}

2019/11/27: PowerShell 7 Preview 5+现已支持&&运算符:

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


3
回复:“荒谬的是他们会删除” - 我不希望把PowerShell想象成“只是去掉了一些愚蠢部分的CMD”。http://is.gd/k92B - Jay Bazuzi
175
我不喜欢把PowerShell看作是“去掉了傻瓜部分的CMD”。我更愿意把它看作是“没有任何有用元素的Bash”。 - Pod
33
在命令行中,你也可以执行 build ; if ($?) { run_tests }。将其翻译成中文为:你也可以在命令行上执行 build ; if ($?) { run_tests } - docwhat
38
学习PowerShell最快遇到挫折的方法就是认为它只是扩展了CMD或bash。实际上,它具有根本不同的模型,尤其是在输入、输出、管道和结果方面。建议开始时阅读一份好的教程或概述,并不要试图让其他shell的语法奏效。必须按照PowerShell自身的规则来学习。 - Mark Meuer
13
如何按照PowerShell的术语运行一个指令,只有当该指令成功后才运行另一个指令?我认为这并不是将bash的思想强加于PowerShell上,而是基本的shell功能。到目前为止,我看到的最好的方法是build ; if ($?) { run_tests },从现在开始我会使用它。希望PowerShell团队能添加&&支持! - Nate
显示剩余11条评论

32

&&|| 在需要实现的功能列表中(目前仍在), 但并不是下一个最有用的添加项。原因是我们已经有了-AND-OR

如果您认为这很重要,请在Connect上提交建议,我们将考虑在V3中实现它。


13
我已经在Connect注册并自荐参与powershell,但我不知道如何提出建议。Connect网站非常复杂和令人困惑 :-( - Orion Edwards
6
我找不到现成的请求,所以我创建了一个:https://connect.microsoft.com/PowerShell/feedback/details/778798/implement-the-and-operators-that-bash-has - Andy Arismendi
37
你知道,问题仍然是如何编写一个等效的表达式,如果你能加上一个使用“-AND”的例子,你的答案会更有用。 - Kyeotic
6
它很重要,因为在比Windows古老得多的系统中,它是一种基本的流程控制工具,已经使用了几乎永恒的时间。因此,它又展示了Linux和Windows之间的另一个不同点。 - airtonix
10
我希望 Jeffrey Snover 正在听着,这个 Stack Overflow 的内容已经足够让他们立即实现了。等待的时间太长了,现在 PowerShell 开始在一些地方弹出,比如 VSCode 在 Windows 中将其用作默认终端。没有 && 真是太痛苦了,而 -and 则会吞噬输出,根本不等同。 - Ciantic
显示剩余4条评论

23

试试这个:

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

15
注意:如果第一个命令失败,第二个命令仍将运行。 - BrunoLM
4
$ErrorActionPreference 首选项变量仅控制_cmdlets_报告的非终止错误的处理方式。外部实用程序如 csca.exe 从不报告此类错误(它们仅反映其退出状态在 $?(成功标志)和 $LASTEXITCODE(报告的特定退出代码)中),因此您的命令行相当于 无条件 执行 两个 命令(相当于 cmdcsc /t:exe /out:a.exe SomeFile.cs & a.exe)。 - mklement0
但是这个命令确实保留了命令输出。 - SabbeRubbish

21

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

cmd /c "command1 && command2"

这里的 && 是由命令行语法描述的 这个问题 提供的。


谢谢!这绝对是最好的答案,因为结果尽可能接近本地使用CMD。对我来说,它完美地运行了,我需要在Windows上使用Gitlab-Runner,在那里CMD支持现已过时...由于PowerShell没有与&&或||链接命令相同的行为,我真的必须在Powershell中“内部”使用CMD,类似于: PS C:\Users\myusername> cmd /c "where ssh-agent || echo Need to install OpenSSH or GIT on this Runner" - MMJ
小提示:在 Powershell 中,如果您需要使用与 CMD 中相同的“where” 命令,请不要直接使用“where”,而是需要使用带有扩展名的“where.exe”,因为没有扩展名时,Powershell 会使用其自己版本的"where"命令别名。 - MMJ

8

我在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,证明第二个条件(Get-Content "C:\MyTxt.txt")没有被执行,这是整个命令的false导致的。


1
你是对的!这个表现就像 && 运算符。即使右边有 $(),也不会让它被评估! - Falco Alexander

4

虽然这是一个很老的问题,但对于新手来说:也许此问题所寻找的PowerShell版本(类似但不等同于)可以使用以下-and

(build_command) -and (run_tests_command)


3
这可能对您的用例来说没问题,但它的行为不像“&&”,因为它忽略了“build_command”的退出代码。 - Simon Buchan
这绝对不是正确的做法。即使第一个命令失败了,它也会运行第二个命令。 - Nate
这完全是错误的。在cmd中,;相当于&,在bash中相当于;。它绝对不同于cmd中的&& - phuclv
2
它还会为两个进程静音STDOUT和STDERR。 - Dragas
经过多次编辑,这个重复了被接受的答案 https://dev59.com/cHRB5IYBdhLWcg3wpYmo#564092 - janv8000

4

只需安装PowerShell 7 (点击此处,滚动并展开资产部分)。 此版本已实现管道链操作符。


3

一种冗长的等价方式是将$LASTEXITCODE-eq 0组合起来:

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

我不确定为什么if ($?)对我无效,但这个可以。

1
检查 $LASTEXITCODE 确实是最健壮的方法,因为不幸的是 $? 在使用 2> 重定向时可能会产生错误的负面影响;请参见此答案 - mklement0

2

在2023年,你可以在PowerShell中使用;运算符。

&&似乎不起作用。


1
分号;一直都是有效的。它的操作方式与&&的概念根本不同。正如OP在问题中提到的那样,&&保证前面的命令必须成功完成,后面的命令才能运行。用分号;将它们分开并没有这个保证。 - Jesse

1

我也遇到了同样的问题。原因是我正在使用旧版本的PowerShell(我已经升级到Windows 11)。要检查版本,请在PowerShell中键入以下内容:$PSVersionTable

我发现我实际上正在使用版本5,而最新版本是7.4。

PSVersion                      5.1.22621.963
PSEdition                      Desktop

安装最新版本(可以单独下载或直接前往Microsoft Store),并确保您已成功切换到新版本(您可能需要额外配置来选择此版本,因为它安装的是新版本而不是替换旧版本)。

PSVersion                      7.3.2
PSEdition                      Core

我升级到最新版本后,&&的功能完美运作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接