我遇到了一个令人头痛的问题。
我想在后台执行多个命令,所以我想在 bash 中逐个启动它们。在 Linux Shell 中在后台启动一个命令很容易,就像这样:
myCommand &
启动多个命令也很容易,就像这样:
myCommand1 && myCommand2
或者
myCommand1 ; myCommand2
但是如果我想在后台运行多个命令,我尝试了以下命令格式,但失败了:
myCommand1 & && myCommand2 &
或者
myCommand1 & ; myCommand2 &
两种格式都失败了。如何才能&
在一个命令行中运行多个命令?
答案1
使用 ()。
如果您想按顺序运行它们:
(myCommand1; myCommand2) &
或者
(myCommand1 &) && (myCommand2 &)
如果您希望它们并行运行:
myCommand1 & myCommand2 &
在 bash 中你也可以使用这个({ 和 ; 后面的空格是必需的):
{ myCommand1 && myCommand2; } &
答案2
我想你想要这个:
myCommand1 & myCommand2 &
这将启动myCommand1
并将其发送到后台,因为它后面跟着一个 & 符号,然后立即启动myCommand2
并将其发送到后台,从而再次释放 shell。
列表
为了更好地理解,你可以替换管道经过命令这里。
列表是由其中一个运算符分隔的一个或多个管道的序列;,&,&&, 或者||,并可选择以下列之一终止 ;,&, 或者 。
如果控制操作员终止命令&,shell 在子 shell 中在后台执行命令。shell 不会等待命令完成,返回状态为 0。命令之间用;按顺序执行;shell 等待每个命令依次终止。返回状态是最后执行的命令的退出状态。
AND 和 OR 列表是一个或多个管道的序列,由 && 和 ||控制运算符。
资料来源:man bash
让我们将其分解成示例。您可以通过组合命令并使用以下任一命令分隔它们来构建列表; & && ||
::
command1 ; command2 # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2 # runs simultaneously
您可以使用以下之一终止列表:; & <newline>
。通常,您可以通过按 (相当于 )
来执行命令或列表。分号的作用完全相同,尤其是在脚本中。但是,Ampersand 会在后台的子 shell 中启动命令,并立即释放 shell。Enter<newline>
;
&
您可以使用圆括号()
或花括号{}
进一步分组列表,区别在于圆括号会生成子 shell,而花括号则不会。花括号在第一个括号后需要一个空格,在结束括号前需要一个分号或换行符。例如:
# if c1 succeeds start a shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) &
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &
如果您不确定使用true
并false
测试构造是否按预期工作,这可能会变得相当复杂:
$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2
作业控制
该jobs
命令显示当前 shell 中正在运行或最近完成的后台作业列表。有许多用于作业控制的键盘快捷键和命令:
- Ctrl+Z键入暂停导致当前在前台运行的进程停止的字符,该进程不会被终止,但仍保留在列表
jobs
中 - Ctrl+Y键入延时暂停当当前在前台运行的进程尝试从终端读取输入时,该进程将被停止
fg
=%
将一个进程带到前台,如果需要则启动它,您可以按如下方式指定该进程:% # last process in the jobs list %1 # 1st process in the jobs list %abc # process beginning with the string “abc” %?abc # process containing the string “abc” anywhere
bg
=%&
如果有必要,将进程置于后台启动:%& # last process in the jobs list %1& # 1st process in the jobs list %abc& # process beginning with the string “abc” %?abc& # process containing the string “abc” anywhere
wait
等待后台进程完成并返回其终止状态:wait %1 # 1st process in the jobs list
想象一下,你开始了一个漫长的过程(
jobs
显示其编号为 3),然后意识到你想让计算机在完成时暂停,并且echo
如果该过程没有成功,还会显示一条消息:wait %3 || echo failed ; systemctl suspend