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.

rubo77
la source

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
AleksanderKseniya
la source
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

slm
la source
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
Mikeserv
la source
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
rubo77
la source
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.

gcb
la source
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
Robin A. Meade
la source
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!

Tom Hale
la source