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
Duplichiamo lo stdout originale su fd 3 (3>&1
) in modo da poterlo ripristinare per slowprocess.sh
(>&3
), mentre stdout per il resto del (...)
subshell va alla pipe a read -t 3
.
In alternativa, se vuoi usare timeout
(qui assumendo GNU timeout
):
timeout --foreground 3 sh -c './slowprocess.sh;exit'
eviterebbe slowprocess.sh
essere ucciso (l';exit
è necessario per sh
implementazioni che si ottimizzano eseguendo l'ultimo comando nel processo della shell).
Ecco una soluzione che utilizza solo gli onnipresenti strumenti della shell.
Questo dovrebbe essere fatto facilmente biforcando il processo lento e un sleep
in background e in attesa che il primo finisca, tranne il wait
shell incorporata attende all lavori da finire piuttosto che solo per il primo.
Quindi, invece, biforca il processo lento e un sleep
in background, chiedi a entrambi di segnalare il proprio stato tramite una pipe e leggere il primo stato che esce dalla pipe.
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"