70

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

$ command1; command2

或者,如果我只想command2command1成功时运行,请使用&&

$ command1 && command2

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

顺便说一句,什么是正确的术语是什么Ctrl-z

4

2 回答 2

95

以下应该做到这一点:

(command1; command2)

注意添加的括号。

于 2012-11-28T08:03:40.803 回答
11

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

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

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

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

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

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

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

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

If you look at stty -a you will see something like this:

susp = ^Z; 

So you can alter it, hence the phrase "typically". Don't do that though, it will confuse the heck out of everyone. The terminal driver raises a SIGTSTP signal which is trapped by Bash.

于 2012-11-28T08:45:30.657 回答