在后台运行两个脚本?&& 和 & 不起作用?

d-b*_*d-b 14 zsh background-process

我想在后台相继运行两个 shell 脚本,最好也使用nohup.

我从

% nohup a.sh &
Run Code Online (Sandbox Code Playgroud)

a这在后台运行。

% nohup a.sh && nohup b.sh
Run Code Online (Sandbox Code Playgroud)

运行a然后b(如果a成功)

但如何在后台启动最后一个组合呢?

如果我做

% nohup a.sh && nohup b.sh &
Run Code Online (Sandbox Code Playgroud)

a将在前台运行,阻止提示符,然后b在后台启动,将控制权返回给提示符。

% nohup a.sh & && nohup b.sh &
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误:zsh: parse error near '&&'

如何在后台启动两个进程?

Sté*_*las 27

这是 zsh 与 sh(或 csh)相比的已知偏差之一。

\n

在sh中:

\n
A && B &\n
Run Code Online (Sandbox Code Playgroud)\n

是缩写:

\n
(A && B) &\n
Run Code Online (Sandbox Code Playgroud)\n

也就是说,它运行一个子 shell,该子 shell 在后台/异步运行该和/或列表。

\n

在 zsh 中,

\n
A && B &\n
Run Code Online (Sandbox Code Playgroud)\n

同步运行A,等待,如果成功,则B在后台/异步运行。

\n

其手册中对此进行了说明(请参阅 参考资料info zsh list):

\n
\n

列表是零个或多个子列表的序列,其中每个子列表都以;&&|&!换行符结尾。当列表作为复杂命令出现在(...)或中时,可以选择从列表中的最后一个子列表中省略此终止符{...}。当子列表由;或 换行符终止时,shell 会等待其完成,然后再执行下一个子列表。 如果子列表由&&|或终止&!,则 shell 在后台执行其中的最后一个管道,并且不等待它完成(请注意与在后台执行整个子列表的其他 shell 的区别)。后台管道\n返回状态为零。

\n
\n

(强调我的)。

\n

常见问题解答中

\n
\n

在 zsh中cmd1 && cmd2 &,仅cmd2而不是整个表达式在后台运行。该手册暗示这是一个错误。用作{ cmd1 && cmd2 } &解决方法。

\n
\n

A && B要像其他 shell 一样在后台运行子 shell ,请使用:

\n
(A && B) &\n
Run Code Online (Sandbox Code Playgroud)\n

或者按照常见问题解答条目的建议:

\n
{A && B} &\n
Run Code Online (Sandbox Code Playgroud)\n

这是等效的,因为如果必须异步运行,我们无论如何都需要派生一个进程(并且主 shell 进程同时继续执行脚本的其余部分)。

\n

所以在这里:

\n
(nohup a.sh && nohup b.sh) &\n
Run Code Online (Sandbox Code Playgroud)\n

不过,如果您只是希望运行该子 shell 的进程及其生成的其他进程不受 SIGHUP 信号的影响:

\n
(trap \'\' HUP; A && B) &\n
Run Code Online (Sandbox Code Playgroud)\n

(您还可以添加一些< /dev/null >> nohup.out 2>&1以更接近地模仿 nohup)

\n

相反,如果您希望在其他类似 sh 的 shell 中获得与 zsh 相同的行为:

\n
A && { B & }\n
Run Code Online (Sandbox Code Playgroud)\n

(请记住,在 zsh 以外的 shell 中,当未启用作业控制时,异步运行的列表的 stdin 会重定向到 /dev/null

\n
\n

\xc2\xb9 偏差可能是无意的,因为2000 年之前的文档措辞进行了更改以修复它以与实际行为保持一致(这可以追溯到 1990 年的 zsh 1.0)描述了嘘行为。这也是自 1997 年以来“手册暗示这是一个错误” 的常见问题解答的结论。但现在改变它已经太晚了(但有人认为应该在 sh、csh 或 ksh 模拟中改变它)。

\n


roa*_*ima 8

您必须将这两个命令组合在一起:

nohup sh -c 'a.sh; b.sh' &
Run Code Online (Sandbox Code Playgroud)

如果您只想在成功退出时运行,请替换;&&b.sha.sh