appuyez sur la touche Espace pour continuer


74

Comment puis-je arrêter un script bash jusqu'à ce qu'un utilisateur ait appuyé Space?

J'aimerais avoir la question dans mon script

Appuyez sur espace pour continuer ou sur CTRL+ Cpour quitter

et alors le script devrait s'arrêter et attendre jusqu'à ce que vous appuyiez sur Space.




Réponses:


58

Vous pouvez utiliser read:

read -n1 -r -p "Press space to continue..." key

if [ "$key" = '' ]; then
    # Space pressed, do something
    # echo [$key] is empty when SPACE is pressed # uncomment to trace
else
    # Anything else pressed, do whatever else.
    # echo [$key] not empty
fi

12
Vous devez ajouter -s pour ne pas imprimer le caractère saisi sur le terminal. Et ajoutez un saut de ligne à la fin, sinon la sortie continuera directement sur la même ligne que la question. Le mieux serait:read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
rubo77

1
Ce script ne fonctionne pas. Je viens juste de le tester sur Red Hat Linux ... Le elsebloc est toujours exécuté, même lorsque la barre d'espace est enfoncée.
robert

3
@ Robert C'est parce que vous n'utilisez pas bash. Cela fonctionne si vous utilisez à la read _place, si vous avez un autre shell que bash.
Niklas Rosencrantz

Le doit-il ''contenir un espace à l'intérieur?
Jose Antonio Dura Olmos

Ceci est ''pour une chaîne vide. Pas d'espace à l'intérieur. Je suppose que ça va aussi, si vous entrez ENTER ou TAB
rubo77

45

La méthode décrite dans ce SO Q & R est probablement le meilleur candidat pour une alternative au pausecomportement auquel vous êtes habitué sous Windows lorsque vous créez des fichiers BAT.

$ read -rsp $'Press any key to continue...\n' -n1 key

Exemple

Ici, je lance ce qui précède et appuie simplement sur n’importe quelle touche, dans ce cas la Dtouche.

$ read -rsp $'Press any key to continue...\n' -n1 key
Press any key to continue...
$ 

Références


Je veux dire pourquoi l' $avant la chaîne ici -rsp $'Press:?
rubo77

2
@ rubo77 - ah. C'est ainsi que vous pouvez créer une chaîne littérale avec des caractères spéciaux. C'est de la forme: $ '...'
slm

1
@ rubo77 - c'est différent. C'est un signe dollar avec guillemets doubles, j'ai utilisé un dollar avec guillemets simples. S'il vous plaît supprimer ce commentaire, c'est faux.
slm

1
Ah je comprends. Si vous placez des séquences d'échappement dans la chaîne d'invite. voir wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
rubo77

@ rubo77 - oui, cette notation permet d'inclure des séquences d'échappement sans echo -e "..."lignes supplémentaires . C'est beaucoup plus compact dans ces situations.
slm

6
hold=' '
printf "Press 'SPACE' to continue or 'CTRL+C' to exit : "
tty_state=$(stty -g)
stty -icanon
until [ -z "${hold#$in}" ] ; do
    in=$(dd bs=1 count=1 </dev/tty 2>/dev/null)
done
stty "$tty_state"

Ceci imprime maintenant une invite sans fin de ligne, gère de CTRL+Cmanière fiable, appelle sttyseulement aussi souvent que nécessaire et restaure le tty de contrôle à exactement l'état dans lequel sttyil l'a trouvé. Recherchez man sttydes informations sur la manière de contrôler explicitement les échos, les caractères de contrôle, etc.

Vous pourriez aussi faire ceci:

printf "Press any key to continue or 'CTRL+C' to exit : "
(tty_state=$(stty -g)
stty -icanon
LC_ALL=C dd bs=1 count=1 >/dev/null 2>&1
stty "$tty_state"
) </dev/tty

Vous pouvez le faire avec ENTER, pas de [test ]et pas sttycomme:

sed -n q </dev/tty

5

Vous pouvez créer une fonction pour cela:

pause(){
 read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
}

Ensuite, vous pouvez l'utiliser partout dans votre script:

pause

si vous débutez dans les scripts shell - vous devez placer la fonction en haut de votre script avant de l'utiliser
Richard

3

paresseux one liner:

echo "Press any key to continue or Ctrl+C to cancel"
read && do_something.sh

l'inconvénient est que vous perdez le contrôle lorsque l'utilisateur appuie sur ctrl + c. Le script se terminera toujours avec le code 130 dans ce cas.


2

Les paramètres IFSpermettant de vider la chaîne suppriment le comportement par défaut de la délimitation des blancs en lecture.

try_this() {
  echo -n "Press SPACE to continue or Ctrl+C to exit ... "
  while true; do
    # Set IFS to empty string so that read doesn't trim
    # See http://mywiki.wooledge.org/BashFAQ/001#Trimming
    IFS= read -n1 -r key
    [[ $key == ' ' ]] && break
  done
  echo
  echo "Continuing ..."
}
try_this

MISE À JOUR 2018-05-23: Nous pouvons simplifier cela en utilisant la variable REPLY, qui n'est pas sujette au fractionnement de mots:

try_this() {
  echo -n "Press SPACE to continue or Ctrl+C to exit ... "
  while true; do
    read -n1 -r
    [[ $REPLY == ' ' ]] && break
  done
  echo
  echo "Continuing ..."
}
try_this

1

Voici un moyen qui fonctionne à la fois bashet zshet qui assure les E / S vers le terminal:

# Prompt for a keypress to continue. Customise prompt with $*
function pause {
  >/dev/tty printf '%s' "${*:-Press any key to continue... }"
  [[ $ZSH_VERSION ]] && read -krs  # Use -u0 to read from STDIN
  [[ $BASH_VERSION ]] && </dev/tty read -rsn1
  printf '\n'
}
export_function pause

Mettez-le dans votre .{ba,z}shrcpour la grande justice!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.