Con ksh/bash/zsh:
{
(./slowprocess.sh >&3 3>&-; echo "$?") |
if read -t 3 status; then
echo "Cool it completed with status $status, do stuff..."
else
echo "It didn't complete, do something else..."
fi
} 3>&1
Duplicamos la salida estándar original en fd 3 (3>&1
) para que podamos restaurarlo para slowprocess.sh
(>&3
), mientras que stdout para el resto de (...)
subshell va a la tubería a read -t 3
.
Alternativamente, si desea utilizar timeout
(aquí asumiendo GNU timeout
):
timeout --foreground 3 sh -c './slowprocess.sh;exit'
evitaría slowprocess.sh
ser asesinado (el ;exit
es necesario para sh
implementaciones que optimizan ejecutando el último comando en el proceso de shell).
Aquí hay una solución que usa solo herramientas de shell ubicuas.
Esto debería hacerse fácilmente bifurcando el proceso lento y un sleep
en segundo plano y esperando a que termine el primero, excepto que el wait
shell incorporado espera todos trabajos para terminar en lugar de solo para el primero.
Entonces, en su lugar, bifurque el proceso lento y un sleep
en segundo plano, haz que ambos informen su estado a través de una tubería y lean el primer estado que sale de la tubería.
fifo=$(mktemp -u) # if not on Linux, adapt to what your OS provides
mkfifo -m 600 "$fifo"
{ ./slowprocess.sh; echo z >"$fifo"; } &
sh -c 'sleep 3; echo a' >"$fifo" &
sleep_pgid=$!
read status <$fifo
case $status in
a) echo "That process is taking a long time"; read ignored <$fifo;;
z) echo "Done already"; kill -INT -$sleep_pgid;;
esac
rm "$fifo"