J'ai un script shell qui lit à partir d'une entrée standard . Dans de rares cas, personne ne sera prêt à apporter une contribution et le script doit expirer . En cas de dépassement de délai, le script doit exécuter du code de nettoyage. Quelle est la meilleure façon de faire ça?
Ce script doit être très portable , y compris pour les systèmes unix du XXe siècle sans compilateur C et pour les périphériques intégrés exécutant busybox. Perl, bash, tous les langages compilés et même le POSIX.2 complet ne peuvent pas être fiables. En particulier, $PPID
, read -t
et parfaitement pièges conformes POSIX ne sont pas disponibles. L'écriture dans un fichier temporaire est également exclue; le script peut s'exécuter même si tous les systèmes de fichiers sont montés en lecture seule.
Juste pour rendre les choses plus difficiles, je veux aussi que le script soit raisonnablement rapide quand il n’expire pas. En particulier, j'utilise également le script sous Windows (principalement sous Cygwin), où fork et exec sont particulièrement faibles, je souhaite donc limiter leur utilisation au minimum.
En un mot, j'ai
trap cleanup 1 2 3 15
foo=`cat`
et je veux ajouter un délai d'attente. Je ne peux pas remplacer cat
par la fonction read
intégrée. En cas de dépassement de délai, je veux exécuter la cleanup
fonction.
Arrière-plan: ce script consiste à deviner l'encodage du terminal en imprimant des caractères de 8 bits et en comparant la position du curseur avant et après. Le début du script vérifie que stdout est connecté à un terminal pris en charge, mais parfois l'environnement est menteur (par exemple, des plink
ensembles TERM=xterm
même s'il est appelé avecTERM=dumb
). La partie pertinente du script ressemble à ceci:
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
Comment puis-je modifier le script pour que si tr
aucune entrée ne soit lue après 2 secondes, elle soit supprimée et que le script exécute la cleanup
fonction?