web-dev-qa-db-fra.com

Entrée utilisateur avec timeout

J'utilise un script pour gérer des choses sur des plongées externes. À la fin, je souhaite donner à l'utilisateur la possibilité de quitter ou de démonter les lecteurs. J'aimerais ajouter un délai d'attente et utiliser la deuxième option (ne rien faire) si l'utilisateur n'a pas répondu.

Je suis assez nouveau sous Linux et les références que j'ai trouvées jusqu'ici sont bien trop énigmatiques pour mon niveau de linux actuel. Il semble que les rédacteurs de Reference supposent que tout le monde parle déjà couramment Linux. :)

Comment puis-je ajouter un délai d'expiration ou une meilleure façon de procéder avec un délai d'expiration et une action par défaut?

note: "myDrives" est mon propre programme pour gérer la fermeture de fichiers, etc. et le démontage

echo "Do you want to un-Mount the External Drives?"
echo ""
select yn in "yes" "no"; do
  case $yn in
    yes ) Sudo myDrives --unmount; 
          break;;
    no ) break;;
  esac
done
kill -9 $PPID
3
LinuxFerLife

Voici une façon de le faire, en utilisant l’option -t timeout de la bash read intégrée:

#!/bin/bash

while :
do
  read -t10 -p "Do you want to un-Mount the External Drives? (Y/N): "
  if [ $? -gt 128 ]; then
    echo "timed out waiting for user response"
    break
  fi

  case $REPLY in
  [yY]*)
    echo "do it"
    break
    ;;
  [nN]*)
    echo "don't do it"
    break
    ;;
  *) echo "Please enter Y or N"
     ;;
  esac
done

Voir help read à partir de l'invite bash ou man bash.

3
steeldriver

Voici une autre façon de le faire:

#!/bin/bash

printf "%s\n" "Do you want to un-Mount the External Drives?" 
timeout --foreground 10 bash -c '
    select sel in "yes" "no"
    do
        echo "$REPLY"
        break
    done' | while read -r answer; do
        echo ">>Got from user: $answer"
        case "$answer" in
            "yes") echo "Unmounting stuff" ;;
        esac
done

Points clés à noter:

  • timeout nécessite un processus réel, pas une commande Shell. Ici, nous générons bash Shell en tant que processus séparé et le laissons faire le travail de conduite select.
  • printf est utilisé en dehors de timeout pour éviter d'envoyer son texte via un canal
  • while read -r answer; do . . .done fonctionnera si et seulement s'il a reçu quelque chose via un tuyau. Ainsi, si le processus bash précédent a expiré, il ne fonctionnera pas - votre action par défaut consiste à ne rien faire.
  • si la boucle while a reçu quelque chose via un tuyau, il vérifiera s'il s'agit de la réponse yes, sinon - cela ne fera rien
1