当我在运行 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