GNU/Linux >> Tutoriels Linux >  >> Linux

Expiration du délai dans un script shell ?

J'ai un script shell c'est la lecture à partir de l'entrée standard . Dans de rares circonstances, personne ne sera prêt à fournir une contribution et le script doit expirer . En cas d'expiration du délai, le script doit exécuter du code de nettoyage. Quelle est la meilleure façon de procéder ?

Ce script doit être très portable , y compris aux systèmes Unix du XXe siècle sans compilateur C et aux périphériques embarqués exécutant busybox, de sorte que Perl, bash, tout langage compilé et même le POSIX.2 complet ne peuvent pas être invoqués. En particulier, $PPID , read -t et les pièges parfaitement 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 ne s'écoule pas. En particulier, j'utilise aussi le script sous Windows (principalement dans Cygwin), où fork et exec sont particulièrement bas, donc je veux garder 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 avec le read intégré. En cas de timeout, je veux exécuter le cleanup fonction.

Contexte :ce script devine l'encodage du terminal en imprimant des caractères 8 bits et en comparant la position du curseur avant et après. Le début du script teste que stdout est connecté à un terminal pris en charge, mais parfois l'environnement ment (par exemple plink définit TERM=xterm même s'il est appelé avec TERM=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 n'a lu aucune entrée après 2 secondes, il est tué et le script exécute le cleanup fonction ?

Réponse acceptée :

Qu'en est-il de ceci :

foo=`{ { cat 1>&3; kill 0; } | { sleep 2; kill 0; } } 3>&1`

C'est-à-dire :exécutez la commande produisant la sortie et sleep dans le même groupe de processus, un groupe de processus rien que pour eux. La commande renvoyée en premier tue tout le groupe de processus.

Quelqu'un se demanderait-il :Oui, le tuyau n'est pas utilisé; il est contourné à l'aide des redirections. Le seul but est que le shell exécute les deux processus dans le même groupe de processus.

En relation :Un script pour réduire et compresser les images de disque DMG ne semble pas bien fonctionner dans le scénario ?

Comme Gilles l'a souligné dans son commentaire, cela ne fonctionnera pas dans un script shell car le processus de script serait tué avec les deux sous-processus.

Une façon¹ de forcer une commande à s'exécuter dans un groupe de processus distinct consiste à démarrer un nouveau shell interactif :

#!/bin/sh
foo=`sh -ic '{ cat 1>&3; kill 0; } | { sleep 2; kill 0; }' 3>&1 2>/dev/null`
[ -n "$foo" ] && echo got: "$foo" || echo timeouted

Mais il peut y avoir des mises en garde avec cela (par exemple, lorsque stdin n'est pas un tty ?). La redirection stderr est là pour se débarrasser du message "Terminé" lorsque le shell interactif est tué.

Testé avec zsh ,bash et dash . Mais qu'en est-il des anciens ?

B98 suggère le changement suivant, fonctionnant sur Mac OS X, avec GNU bash 3.2.57, ou Linux avec tiret :

foo=`sh -ic 'exec 3>&1 2>/dev/null; { cat 1>&3; kill 0; } | { sleep 2; kill 0; }'`



Linux
  1. Déterminer Shell dans le script pendant l'exécution ?

  2. Déterminer le chemin d'accès au script shell sourcé ?

  3. Comment gérer les commutateurs dans un script shell ?

  4. Comment créer un fichier temporaire en script shell ?

  5. Masquer le mot de passe dans les scripts shell ?

Comment utiliser des variables dans les scripts Shell

Comment créer des scripts shell

Comment exécuter une commande dans un script shell ?

Un fichier .sh peut-il être un malware ?

déterminer le shell dans le script pendant l'exécution

Exécuter un script shell en tant qu'utilisateur différent