Ich habe ein Shell-Skript , das von der Standardeingabe liest . In seltenen Fällen ist niemand bereit, Eingaben zu machen, und das Skript muss eine Zeitüberschreitung aufweisen . Im Falle einer Zeitüberschreitung muss das Skript einen Bereinigungscode ausführen. Wie geht das am besten?
Dieses Skript muss sehr portabel sein , einschließlich für Unix-Systeme des 20. Jahrhunderts ohne C-Compiler und für eingebettete Geräte, auf denen busybox ausgeführt wird. Perl, bash, jede kompilierte Sprache und sogar das vollständige POSIX.2 können daher nicht verwendet werden. Insbesondere $PPID
, read -t
und perfekt POSIX-kompatibele Fallen sind nicht verfügbar. Das Schreiben in eine temporäre Datei ist ebenfalls ausgeschlossen. Das Skript wird möglicherweise auch dann ausgeführt, wenn alle Dateisysteme schreibgeschützt bereitgestellt sind.
Um die Sache noch schwieriger zu machen, möchte ich auch, dass das Skript einigermaßen schnell ist, wenn keine Zeitüberschreitung auftritt. Insbesondere verwende ich das Skript auch in Windows (hauptsächlich in Cygwin), wo Fork und Exec besonders niedrig sind, so dass ich ihre Verwendung auf ein Minimum beschränken möchte.
Kurz gesagt, ich habe
trap cleanup 1 2 3 15
foo=`cat`
und ich möchte eine Auszeit hinzufügen. Ich kann nicht cat
mit dem read
eingebauten ersetzen . Im Falle eines Timeouts möchte ich die cleanup
Funktion ausführen .
Hintergrund: Dieses Skript errät die Codierung des Terminals, indem es einige 8-Bit-Zeichen druckt und die Cursorposition davor und danach vergleicht. Der Anfang des Skripts testet, dass stdout mit einem unterstützten Terminal verbunden ist, aber manchmal lügt die Umgebung (z. B. plink
setzt, TERM=xterm
auch wenn es mit aufgerufen wirdTERM=dumb
). Der relevante Teil des Skripts sieht folgendermaßen aus:
text='Éé' # UTF-8; shows up as Ãé on a latin1 terminal
csi='␛['; dsr_cpr="${csi}6n"; dsr_ok="${csi}5n" # ␛ is an escape character
stty_save=`stty -g`
cleanup () { stty "$stty_save"; }
trap 'cleanup; exit 120' 0 1 2 3 15 # cleanup code
stty eol 0 eof n -echo # Input will end with `0n`
# echo-n is a function that outputs its argument without a newline
echo-n "$dsr_cpr$dsr_ok" # Ask the terminal to report the cursor position
initial_report=`tr -dc \;0123456789` # Expect ␛[42;10R␛[0n for y=42,x=10
echo-n "$text$dsr_cpr$dsr_ok"
final_report=`tr -dc \;0123456789`
cleanup
# Compute and return initial_x - final_x
Wie kann ich das Skript so ändern, dass tr
es beendet wird und das Skript die cleanup
Funktion ausführt , wenn nach 2 Sekunden keine Eingabe gelesen wurde ?