Dado que el guión proporcionado por Josh Arenberg podría tener algunos problemas de bloqueo (que no experimenté hasta ahora, pero que tampoco he investigado), he escrito algo por mi cuenta. No debería tener problemas de bloqueo. También funciona para cualquier comando de shell, no solo 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
Crea una cadena de procesos, cada uno esperando el anterior. Si un proceso en el medio de la cadena se bloquea mientras espera (improbable pero no imposible), la cadena se rompe y ambas partes funcionan en paralelo. Lo mismo sucede si uno de los procesos es eliminado.
Uso como este:
q $COMMAND $ARGS
o incluso
q $COMMAND $ARGS; $ANOTHER_COMMAND $MORE_ARGS
Prueba, por ejemplo, escribiendo
q sleep 10 &
q echo blubb &
y descubriendo que después de 10 segundos se imprime blubb.