web-dev-qa-db-ja.com

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秒未満で完了し、まったく動きません。なぜそれが起こったのですか?

7
mareoraft

非対話型シェルでは、完全なジョブ制御はできません。コマンド置換で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
10
cuonglm