Domanda

Ho un paio di programmi shell che parlano su una pipe denominata. Il lettore crea la pipe all'avvio e la rimuove quando esce.

A volte, lo scrittore tenterà di scrivere nella pipe tra il momento in cui il lettore smette di leggere e il tempo in cui rimuove la pipe.

reader: while condition; do read data <$PIPE; do_stuff; done
writer: echo $data >>$PIPE
reader: rm $PIPE

quando ciò accade, lo scrittore si bloccherà per sempre cercando di aprire la pipa per scrivere.

Esiste un modo pulito per concedere un timeout, in modo che non rimanga sospeso fino a quando non viene ucciso manualmente? So di poterlo fare

#!/bin/sh
# timed_write <timeout> <file> <args>
# like "echo <args> >> <file>" with a timeout

TIMEOUT=$1
shift;
FILENAME=$1
shift;
PID=$

(X=0; # don't do "sleep $TIMEOUT", the "kill %1" doesn't kill the sleep
 while [ "$X" -lt "$TIMEOUT" ];
 do sleep 1; X=$(expr $X + 1);
 done; kill $PID) &

echo "$@" >>$FILENAME
kill %1

ma questo è un po 'icky. Esiste un comando o un comando shell per farlo in modo più pulito (senza interrompere il compilatore C)?

È stato utile?

Soluzione 3

Questa coppia di programmi funziona molto più bene dopo essere stata riscritta in Perl usando socket di dominio Unix invece di named pipe. Il problema particolare in questa domanda è scomparso del tutto, poiché se / quando un'estremità muore, la connessione scompare invece di bloccarsi.

Altri suggerimenti

Lo standard UNIX "quot" il modo per gestirlo è utilizzare Expect , che viene fornito con un esempio a tempo: eseguire un programma solo per un determinato periodo di tempo.

Aspettarsi può fare miracoli per lo scripting, vale la pena impararlo. Se non ti piace Tcl, esiste anche un modulo Python Expect .

Questa domanda viene posta periodicamente (anche se non sono riuscito a trovarla con una ricerca). Ho scritto due script di shell da utilizzare come comandi di timeout: uno per le cose che leggono l'input standard e uno per le cose che non leggono l'input standard. Questo puzza, e intendevo scrivere un programma in C, ma non ci sono ancora riuscito. Consiglio vivamente di scrivere un comando timeout in C una volta per tutte. Ma nel frattempo, ecco il più semplice dei due script di shell, che si blocca se il comando legge l'input standard:

#!/bin/ksh

# our watchdog timeout in seconds
maxseconds="$1"
shift

case $# in
  0) echo "Usage: `basename <*>` <seconds> <command> [arg ...]" 1>&2 ;;
esac

"$@" &
waitforpid=$!

{
    sleep $maxseconds
    echo "TIMED OUT: $@" 1>&2 
    2>/dev/null kill -0 $waitforpid && kill -15 $waitforpid
} &
killerpid=$!

>>/dev/null 2>&1 wait $waitforpid
# this is the exit value we care about, so save it and use it when we
rc=$?

# zap our watchdog if it's still there, since we no longer need it
2>>/dev/null kill -0 $killerpid && kill -15 $killerpid

exit $rc

L'altro script è online all'indirizzo http: //www.cs.tufts. edu / ~ nr / drop / timeout .

trap 'kill $(ps -L $! -o pid=); exit 30' 30
echo kill -30 $ 2\>/dev/null | at $1 2>/dev/null
shift; eval $@ &
wait
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top