Поскольку у сценария Джоша Аренберга могут быть проблемы с блокировкой (которые я до сих пор не испытывал, но и не исследовал), я написал кое-что самостоятельно. У него не должно быть проблем с блокировкой. Это также работает для любой команды оболочки, а не только для 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
Он создает цепочку процессов, каждый из которых ожидает предыдущего. Если во время ожидания происходит сбой процесса в середине цепочки (маловероятно, но не невозможно), цепочка разрывается, и обе части работают параллельно. То же самое происходит, если один из процессов убит.
Использование как это:
q $COMMAND $ARGS
или даже
q $COMMAND $ARGS; $ANOTHER_COMMAND $MORE_ARGS
Проверьте, например, набрав
q sleep 10 &
q echo blubb &
и обнаружив, что через 10 секунд распечатывается жир.