Josh Arenbergによって提供されたスクリプトにはいくつかのデッドロックの問題があるかもしれないので(これまで私は経験していませんが、調査もしていません)、自分で何かを書きました。デッドロックの問題はないはずです。また、cpだけでなく、すべてのシェルコマンドで機能します。
Contents of ~/bin/q
#!/bin/bash
#this waits for any PIDs to finish
anywait(){
for pid in "$@"; do
while kill -0 "$pid" 2&>1 >/dev/null; do
sleep 0.5
done
done
}
PIDFILE=~/.q.pid
#open PIDFILE and aquire lock
exec 9>>$PIDFILE
flock -w2 9 || { echo "ERROR: flock() failed." >&2; exit 1; }
#read previous instances PID from PIDFILE and write own PID to PIDFILE
OLDPID=$(<$PIDFILE)
echo $$>$PIDFILE
#release lock
flock -u 9
#wait for OLDPID
anywait $OLDPID
#do stuff
"$@"
#afterwards: cleanup (if pidfile still contains own PID, truncate it)
flock -w2 9 || { echo "ERROR: flock() failed." >&2; exit 1; }
if [ $(<$PIDFILE) == $$ ]; then
truncate -s0 $PIDFILE
fi
flock -u 9
プロセスのチェーンを作成し、それぞれが前のプロセスを待機します。チェーンの途中にあるプロセスが待機中にクラッシュした場合(可能性は低いですが不可能ではありません)、チェーンは切断され、両方の部分が並行して実行されます。プロセスの1つが強制終了された場合も同様です。
このような使用法:
q $COMMAND $ARGS
あるいは
q $COMMAND $ARGS; $ANOTHER_COMMAND $MORE_ARGS
入力してテストする
q sleep 10 &
q echo blubb &
10秒後にblubbが出力されることがわかります。