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秒未満で完了し、まったく動きません。なぜそれが起こったのですか?
非対話型シェルでは、完全なジョブ制御はできません。コマンド置換でjobs
を開始すると、サブシェルで実行されました。このサブシェルでは、実行中のジョブはなく、何も取得されていません。
インタラクティブシェルでは、 MONITORが設定されました 、完全なジョブ制御が可能になりました。この場合、zsh
は、サブシェルに入るときにすべてのジョブをテーブルに格納し、サブシェルにジョブがない場合はそのジョブテーブルを使用します。
zsh
4.3以降では、Shebang行に-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
とにかく、組み込みのすべての子プロセスを待つことができます wait :
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