bashなどでは&
で実行したジョブを待つためのwait
がありますが
fish では wait
コマンドが実装されていません。
そこでバックグラウンドで実行しているジョブを待つためのfunctionを自作してみました
作ったもの
fwait.fish
function fwait
while true
set -l bg_jobs (jobs -p $argv | string match -r "\d*")
if test -z "$bg_jobs"
break
end
end
end
jobs -p
は 現在バックグランドで実行しているジョブのPIDのみを表示します
$ fish -c "sleep 15; echo OK" &
$ jobs
Job Group State Command
1 65801 running fish -c "sleep 15; echo OK" &
$ jobs -p
Process
65801
string match -r "\d*"
は 正規表現に一致するか判定し、
一致したものを返してます
$ jobs -p | string match -r "\d*"
65801
test -z "$bg_jobs"
で bg_jobsが空か判定し、
空だったら(=バックグランドで実行しているジョブがなかったら)while文を抜けるようにしています
動作確認
動作確認用のコード。こちらの記事を参考にさせていただいてます
test.fish
set -l urls "https://"{google,twitter,youtube,facebook,github,qiita}".com"
for url in $urls
fish -c "curl -Lw \"$url: %{time_total}s\n\" -o /dev/null -s $url" &
end
zwait
echo "all OK!"
# fwaitあり
$ time -p fish test.fish
https://qiita.com: 0.345s
https://google.com: 0.515s
https://github.com: 1.085s
https://facebook.com: 1.237s
https://youtube.com: 1.725s
https://twitter.com: 2.084s
all OK!
real 2.46
user 1.39
sys 1.73
# fwaitなし
$ time -p fish test.fish
all OK!
real 0.11
user 0.04
sys 0.04
https://qiita.com: 0.363s
https://google.com: 0.596s
https://facebook.com: 1.055s
https://twitter.com: 1.422s
https://youtube.com: 2.045s