【问题标题】:Run one command after another, even if I suspend the first one (Ctrl-z)一个接一个地运行命令,即使我挂起第一个命令(Ctrl-z)
【发布时间】:2012-11-28 07:53:57
【问题描述】:

我知道在 bash 中我可以通过用分号分隔命令一个接一个地运行,例如

$ command1; command2

或者,如果我只希望 command2 仅在 command1 成功时运行,则使用 &&

$ command1 && command2

这可行,但是如果我使用Ctrl-z 暂停command1,在第一种情况下,它会立即运行command2,而在第二种情况下,它根本不会运行它。如何按顺序运行命令,但仍然能够暂停第一个命令,但在我重新启动它(使用fg)并完成之前不能运行第二个命令?我更喜欢输入尽可能简单的东西,因为我想以交互方式执行此操作。或者也许我只需要在某处设置一个选项。

顺便问一下,Ctrl-z 做什么的正确术语是什么?

【问题讨论】:

  • command1; command2 应该完全符合您的要求。至于术语,Ctrl-Z 暂停进程。
  • 嗯,它没有。我在 iTerm2 的 Mac OS X 10.8 上运行 bash 版本 4.2.8(2)-release
  • 感谢您的术语。我会更新问题以使用它。
  • 是的,你是对的,它没有。我认为您需要一个子shell。看我的回答。

标签: bash shell command signals suspend


【解决方案1】:

以下应该这样做:

(command1; command2)

注意添加的括号。

【讨论】:

  • 太棒了!现在,您或任何人是否愿意解释为什么它在这三种情况下的行为方式(command1; command2command1 && command 2(command1; command2))?
  • 其实我也不确定。也许有人可以启发我们俩。
  • 从技术上讲,您不会使用 Control-z 挂起进程,而是挂起 作业。使用command1; command2,当您按下 Control-z 时,活动作业只是进程command1,因此它被暂停,下一个作业 (command2) 开始。使用(command1; command2),活动作业由运行这两个命令的子shell 组成,因此整个子shell 被Control-z 挂起。您可以通过在暂停每个命令后运行jobs 命令来确认这一点。
  • 谢谢@chepner,那么command1 && command2 选项呢?这是我经常遇到的。即使 job 由两个命令组成,我也注意到第二个命令在后台运行后不会执行。 (command1 && command2) 当然可以,但我经常不知道我想提前后台处理一个进程。否则我会从一开始就将其作为后台作业执行。
  • command1 && command2 实际上是两个作业(一个作业由一个管道组成,&& 列表由两个(单进程)管道组成,command1command2)。第二个命令在command1 退出(状态为零)之前不会运行,command1 在停止时不会退出。
【解决方案2】:

在 Bash 中,当您将作业置于后台(使用 CTRL+Z 或 &)时,它不会等待作业完成,并给出退出代码为零(成功)。您已经观察到了这么多,并记录在 man 页面中。

逻辑“与”&& 的行为是从左到右进行测试。每个部分都必须成功,因此如果第一个部分不成功,则第二个部分将不会运行。因此,使用 && 它从左到右运行命令,直到其中一个失败。成功的定义是退出代码 ($?) 为零。

将此与逻辑“OR”、|| 进行对比,后者从左到右运行命令,直到其中一个工作

@NPE 给出的 subshel​​l 解决方案的解释也可以在man 页面中找到:

'a ; 形式的复合命令和命令序列乙; c' 不是 尝试暂停进程时优雅地处理。当一个进程停止时,shell 立即执行序列中的下一个命令。将命令序列放在括号之间就足够了,以强制它进入一个子shell,它可以作为一个单元停止。

CTRL+Z 的正确术语是 suspend 字符,同样来自 man 页面:

在进程运行时键入挂起字符(通常是 ^Z、Control-Z)会导致该进程停止并将控制权返回给 bash。

(很抱歉引用man页面这么多,但他们真的是你的朋友,值得一读)

如果您查看stty -a,您会看到如下内容:

susp = ^Z; 

所以你可以改变它,因此短语“通常”。但是不要这样做,它会让每个人都感到困惑。终端驱动程序发出一个 SIGTSTP 信号,该信号被 Bash 捕获。

【讨论】:

  • 我还是不明白 && 的行为。暂停进程是否会导致它返回非零值?
  • 这些来自哪些手册页?我想答案可能就在那里,但我什至不知道从哪里开始。
  • && 连接了两个管道,每个管道都是一个单独的作业。 (请注意,管道是由| 连接的一个或多个命令,这意味着command1 在技术上是一个单一的命令管道)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 2013-08-13
相关资源
最近更新 更多