如何在Windows CMD中一行中运行两个命令?

1329

我想在Windows CMD控制台中运行两个命令。

在Linux中,我会这样做

touch thisfile ; ls -lstrh

在Windows上如何实现?

24个回答

1878
自2000年以来,所有微软操作系统都可以像这样做,并且至今仍然适用:
dir & echo foo

如果你只希望在第一个命令成功执行后才执行第二个命令:

dir && echo foo

单个和符号(&)用于在一行上执行多条命令,这可以追溯到Windows XP、Windows 2000和一些较早的NT版本。(至少从4.0开始,根据这里的一位评论者。)

关于此事,您会在本页下滚时发现还有很多其他要点。

以下是历史数据,供那些可能觉得有教育意义的人参考。

在此之前,&&语法只是shell替代品4DOS的一个特性,在将该特性添加到Microsoft命令解释器之前。

在Windows 95、98和ME中,您需要使用管道字符(|):

dir | echo foo

在MS-DOS 5.0及以后的版本中,以及一些早期的Windows和NT版本的命令解释器中,(未公开的)命令分隔符是字符20 (Ctrl+T),我将在此处用^T代表它。
dir ^T echo foo

20
同样适用于Windows 8.0和8.1。 - MEMark
6
@Fallenreaper,在普通的cmd提示符中也有效,所以我想养成这个习惯似乎不错。 :) - user909694
6
请确保你意识到这两者之间的实际区别:请参考Raihan下面的回答。 - Moshe Katz
11
明白。A && B,只有在 A 成功的情况下才会运行 B,而 A & B 则会在 A 运行完后无论结果如何都会运行 B。感谢提醒。 - Fallenreaper
6
@infografnet 这是一个不同的问题。这两个命令都会运行,但环境变量替换将在任何一个命令实际执行之前进行评估。因此,echo %myvar% 将作为 echo OldValueOfMyVar 运行。这个问题可以通过使用延迟扩展功能来解决(只能在批处理文件中使用)。所以在批处理文件内尝试以下操作:setlocal EnableDelayedExpansion && set MyVar=MyVal && echo !MyVar! && endlocal。(注意:该功能要求您在 % 符号的位置上使用 ! 标记。) - Disillusioned
显示剩余12条评论

700

来自文档的一句话:

使用多个命令和条件处理符号

您可以使用条件处理符号从单个命令行或脚本运行多个命令。当您使用条件处理符号运行多个命令时,位于条件处理符号左侧的命令的结果决定位于条件处理符号右侧的命令的行为。

例如,您可能只想在上一个命令失败时运行一个命令。或者,您可能只想在上一个命令成功时运行一个命令。

您可以使用以下表中列出的特殊字符传递多个命令。

  • & [...]
    command1 & command2
    用于在一个命令行上分隔多个命令。Cmd.exe运行第一个命令,然后运行第二个命令。

  • && [...]
    command1 && command2
    仅在符号前面的命令成功时才使用来运行符号后面的命令。Cmd.exe运行第一个命令,仅当第一个命令成功完成时才运行第二个命令。

  • || [...]
    command1 || command2
    仅在符号前面的命令失败时才使用来运行符号后面的命令。Cmd.exe运行第一个命令,仅当第一个命令未成功完成(接收到大于零的错误代码)时才运行第二个命令。

  • ( )[...]
    (命令1 & 命令2)
    用于组合或嵌套多个命令。

  • ; 或 ,
    命令1 参数1;参数2
    用于分隔命令参数。


56
请尝试运行命令 cmd /c "echo foo & echo bar" - Raihan
3
在 Windows 10 上,vagrant up && vagrant ssh 可以正常运行,无需加引号。 - furman87
1
文档链接已失效,请前往新位置 https://technet.microsoft.com/en-us/library/bb490954.aspx。 - nkef
12
&符号并不会使命令异步或并行执行。command1 & command2会在command1完成后运行command2command1的成功或失败都无关紧要。 - bornfromanegg
1
此外,将 & 与 if 语句混合使用可能会有些棘手。要在没有 else 语句的 if 语句之后运行一个命令,请使用 (if condition command1) & command2。不要尝试使用 if condition (command1) & command2,因为 command2 将不会运行。 - GreenRaccoon23
显示剩余6条评论

93

&是Bash中的分号;的等效表示方式(运行命令),&&是Bash中&&的等效表示方式(只有在前一个命令未产生错误时才运行)。


1
这也适用于csh、tcsh和许多其他shell。我以前从未在Linux中看到过; - phuclv
14
在sh样式的shell中,;表示运行第一个命令,并等待它完成后再运行第二个命令。&表示运行第一个命令,将其置于后台,然后运行第二个命令。因此,两个程序同时启动。请注意,这些不是组合符号,它们是第一个命令的尾随符号;您可以使用progname &在没有第二个命令的情况下将单个命令启动到后台。 - M.M

28

如果你想要创建一个 cmd 快捷方式(例如在桌面上),请加上 /k 参数(/k 意味着保留,/c 将关闭窗口):

cmd /k echo hello && cd c:\ && cd Windows

26
你可以使用 & 运行连续的命令。例如:c:\dir & vim myFile.txt

22
您可以使用call来解决环境变量过早被评估的问题 - 例如。
set A=Hello & call echo %A%

2
只有在变量未被设置的情况下才能起作用,否则 echo 将打印出旧值而不是新值。至少,在我的 Windows 7 系统上观察到了这一点。 - Craig M. Brandenburg
我使用 set A= first 来确保变量未设置。 - SSi
4
更好的方法是使用延迟扩展(在脚本中使用setlocal EnableDelayedExpansion 或者 cmd /v)。例如:timeout 5 && cmd /v /c echo !TIME! && echo %TIME% - Nick
11
在第一个百分号后面加上^以获取新值:set A=Hello & call echo %^A%。 - Nicolas
感谢Nick和Nicolas提供的解决方案!我尝试将它们用于更一般的情况,即在set之后有多个使用&分隔的命令,并且我发现只有通过额外的语法技巧才能使其正常工作。对于Nick的解决方案,我应该将命令分隔符转义为^&:set var=Hello & cmd /v /c echo firstUsage=!var! ^& echo secondUsage=!var!。对于Nicolas的解决方案,我应该在每个子命令之前重复callset var=Hello & call echo firstUsage=%^var% & call echo secondUsage=%^var%(可能有人知道如何改进这个)。 - Alexander Samoylov
似乎 cmd 将和号(&)之前的所有内容都解释为属于上一个命令,包括空格。因此,上面的代码将字符串 'Hello '(不带引号)赋值给变量。这在向 PATH 变量添加内容并运行命令时尤其重要(例如 PATH=C:\mydir & myappinmydir 不起作用,因为 PATH 以空格结尾)。请使用 PATH=C:\mydir& myappinmydir(mydir 和 & 之间没有空格)。此外,重定向也是如此,因此 echo hallo > myfile 在文件中添加 hallo 后会有一个空格(请改用 echo hallo> myfile)。 - Johannes Thoma

13

当在同一行运行多个命令时,可以使用许多处理符号,在某些情况下可能会导致处理重定向、在其他情况下更改输出或仅失败。一个重要的情况是将操作变量的命令放置在同一行上。

@echo off
setlocal enabledelayedexpansion
set count=0
set "count=1" & echo %count% !count!

0 1

正如您在上面的示例中看到的那样,当命令使用变量放置在同一行时,您必须使用延迟扩展来更新变量值。如果您的变量是索引的,请使用CALL命令并带有%%修饰符来在同一行上更新其值:

set "i=5" & set "arg!i!=MyFile!i!" & call echo path!i!=%temp%\%%arg!i!%%

path5=C:\Users\UserName\AppData\Local\Temp\MyFile5

给定的例子对我不起作用,但下面这个可以:cmd /V:ON /c "set i=5 & set arg!i!=MyFile!i! & echo path!i!=%temp%\%arg!i!%" - sactiw

11

在Windows系统中,我尝试了上述所有的解决方案&, &&,但都不起作用。最终,';'符号奏效了。

npm install; npm start

这对我来说行不通,因为第二个命令的开始需要等待第一个命令的结果(例如 http-server --port=8081 ; ng build --watch 是行不通的)。 - undefined
@Tony 如果你正在运行一个持续运行的命令,那么它将会一直等待,所以你可以尝试将这些类型的命令在后台运行,或者单独运行另一个命令。 - undefined
1
是的,这就是我在我的回答中指定的内容。https://stackoverflow.com/a/77315356/4255158 - undefined

8
该命令执行指令并在单个命令中打开名为Output.txt的文件。具体翻译如下:

cmd /c ipconfig /all & Output.txt

这条命令执行ipconfig /all指令,并在同一命令中打开Output.txt文件。

8

我想启用运行组件注册表(RegAsm)的特定任务,但问题是结果会在我读取之前一闪而过。为了解决这个问题,我尝试使用 Pause 管道命令,但当命令失败时,它不起作用(如此处所述:Pause command not working in .bat scriptBatch file command PAUSE does not work)。因此,我尝试了 cmd /k 命令,但这会使窗口保持打开状态以等待更多命令(我只需要读取结果)。所以我添加了一个暂停命令,然后是 exit 命令,得到以下内容:

cmd /k C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe "%1" /codebase \"%1\" & pause & exit

这非常有效-- RegAsm 运行文件并显示其结果,然后会出现 "按任意键继续..." 的提示,按下键后命令提示符窗口关闭。

P.S. 对于其他人可能感兴趣的人,您可以使用以下.reg 文件条目将 dllfile 关联到 .dll 文件,然后向其添加 RegAsm 命令扩展名(请注意转义引号和反斜杠):

[HKEY_CLASSES_ROOT\.dll]
"Content Type"="application/x-msdownload"
@="dllfile"

[HKEY_CLASSES_ROOT\dllfile]
@="Application Extension"

[HKEY_CLASSES_ROOT\dllfile\Shell\RegAsm]
@="Register Assembly"

[HKEY_CLASSES_ROOT\dllfile\Shell\RegAsm\command]
@="cmd /k C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\regasm.exe \"%1\" /codebase \"%1\" & pause & exit"

现在我有一个漂亮的右键菜单来注册一个程序集。

1
http://lifehacker.com/get-rid-of-the-word-so-to-increase-your-credibility-1571124119 - Anthon

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