zsh 等待作业完成

zsh 等待作业完成

当我在运行 zsh 的终端中键入以下内容时(每行都是一个命令)

babel www/scripts6/lib/data.js > www/scripts/lib/data.js &
babel www/scripts6/lib/user.js > www/scripts/lib/user.js &
babel www/scripts6/lib/profile.js > www/scripts/lib/profile.js &
babel www/scripts6/lib/d3-and-svg.js > www/scripts/lib/d3-and-svg.js &
babel www/scripts6/main.js > www/scripts/main.js &
while [[ $(jobs) =~ 'babel' ]]; do echo 'moo'; done

它发出大约 3 秒的声音,然后停止。但是当我将相同的代码放入文件中时moo.zsh然后在我的终端中运行它

zsh moo.zsh

它在不到 1 秒的时间内完成,而且根本不会发出呜呜声。为什么会发生这样的事?

答案1

在非交互式 shell 中,您没有完全的作业控制权。当您开始jobs命令替换时,它在子 shell 中运行。在这个子 shell 中,没有作业在运行,你什么也没有。

在交互式 shell 中,监视器已设置,给你完全的工作控制权。在这种情况下,zsh当您进入子 shell 时,将所有作业存储在一个表中,如果子 shell 中没有作业,则将使用该作业表。

在4.3 及更高版本中,您可以通过放置 shebang 行在zsh非交互式 shell 中打开作业控制:-m

#!/usr/bin/zsh -m

或使用setopt

setopt monitor
: The rest of script goes here

检查作业状态的更好方法可以是:

#!/usr/bin/zsh
zmodload zsh/parameter

babel www/scripts6/lib/data.js > www/scripts/lib/data.js &
babel www/scripts6/lib/user.js > www/scripts/lib/user.js &
babel www/scripts6/lib/profile.js > www/scripts/lib/profile.js &
babel www/scripts6/lib/d3-and-svg.js > www/scripts/lib/d3-and-svg.js &
babel www/scripts6/main.js > www/scripts/main.js &

while (( ${#jobstates} )); do
  print "moo"
done

无论如何,您可以使用内置等待所有子进程等待:

babel www/scripts6/lib/data.js > www/scripts/lib/data.js &
babel www/scripts6/lib/user.js > www/scripts/lib/user.js &
babel www/scripts6/lib/profile.js > www/scripts/lib/profile.js &
babel www/scripts6/lib/d3-and-svg.js > www/scripts/lib/d3-and-svg.js &
babel www/scripts6/main.js > www/scripts/main.js &
# Wait for all children
wait
echo END

相关内容