列表

列表

我遇到了一个令人头痛的问题。

我想在后台执行多个命令,所以我想在 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 &

如果您不确定使用truefalse测试构造是否按预期工作,这可能会变得相当复杂:

$ { 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
    

相关内容