Quel est l'équivalent Linux d'une pause DOS?

236

J'ai un script shell Bash dans lequel je voudrais suspendre l'exécution jusqu'à ce que l'utilisateur appuie sur une touche. Sous DOS, cela se fait facilement avec la commande "pause". Existe-t-il un équivalent Linux que je peux utiliser dans mon script?

jt.
la source

Réponses:

329

read est ce que ca:

user@host:~$ read -n1 -r -p "Press any key to continue..." key
[...]
user@host:~$ 

Le -n1spécifie qu'il n'attend qu'un seul caractère. Le le -rmet en mode brut, ce qui est nécessaire car sinon, si vous appuyez sur quelque chose comme une barre oblique inverse, il ne s'enregistre que lorsque vous appuyez sur la touche suivante. Le -pspécifie l'invite, qui doit être citée si elle contient des espaces. L' keyargument n'est nécessaire que si vous voulez savoir sur quelle touche ils ont appuyé, auquel cas vous pouvez y accéder $key.

Si vous utilisez Bash, vous pouvez également spécifier un délai d'expiration avec -t, ce qui provoque l'échec de la lecture lorsqu'une touche n'est pas enfoncée. Ainsi, par exemple:

read -t5 -n1 -r -p 'Press any key in the next five seconds...' key
if [ "$?" -eq "0" ]; then
    echo 'A key was pressed.'
else
    echo 'No key was pressed.'
fi
Jim
la source
5
Strictement parlant, ce serait "Enter any non-NUL character to continue". Certaines touches n'envoient aucun caractère (comme Ctrl...) et certaines en envoient plus d'un (comme F1, Home...). bashignore les caractères NUL.
Stephane Chazelas
2
Habituellement, c'est une meilleure idée de demander une clé spécifique comme entrée, espace ou Y. "N'IMPORTE QUEL" peut être déroutant pour certains utilisateurs, il y a une clé TAB alors pourquoi aucune clé ANY et à coup sûr il y a des clés qui sont potentiellement dangereuses comme ESCAPE, CTRL, CMD, le bouton d'alimentation, etc. Ce n'est plus aussi pertinent aujourd'hui, car de nos jours, la console n'est généralement utilisée que par des utilisateurs d'ordinateurs avancés qui interpréteront correctement "TOUTE touche". Le manuel de conception d'Apple 2, assez ancien, contient une section intéressante consacrée à ce sujet ( apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf ).
Gellweiler
3
Si vous utilisez plutôt le message, Press a key to continue...même les utilisateurs novices pourront trouver la aclé et appuyer dessus; o)
DJDaveMark
1
Cela aura des problèmes avec command | myscript.shou myscript.sh | command. Voir cette réponse pour une solution.
Tom Hale
Si quelqu'un obtient, read: 1: read: Illegal option -nassurez-vous d'encapsuler votre commande, bash -c 'command && command'etc., car cette erreur provient probablement de sh. Je fais cela dans une commande wrapper Lando.
Elijah Lynn
155

J'utilise beaucoup ces méthodes qui sont très courtes, et elles sont comme les solutions @theunamedguy et @Jim, mais avec le timeout et le mode silencieux en plus.

J'aime particulièrement le dernier cas et l'utilise dans de nombreux scripts qui s'exécutent en boucle jusqu'à ce que l'utilisateur appuie Enter.

Commandes

  • Entrez la solution

    read -rsp $'Press enter to continue...\n'
  • Solution d'échappement (avec -d $ '\ e')

    read -rsp $'Press escape to continue...\n' -d $'\e'
  • Toute solution clé (avec -n 1)

    read -rsp $'Press any key to continue...\n' -n 1 key
    # echo $key
  • Question avec choix présélectionné (avec -ei $ 'Y')

    read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;
    # echo $key
  • Solution de temporisation (avec -t 5)

    read -rsp $'Press any key or wait 5 seconds to continue...\n' -n 1 -t 5;
  • Alias ​​amélioré pour le sommeil

    read -rst 0.5; timeout=$?
    # echo $timeout

Explication

-r spécifie le mode brut, qui n'autorise pas les caractères combinés comme "\" ou "^".

-s spécifie le mode silencieux, et parce que nous n'avons pas besoin de sortie clavier.

-p $ ' prompt ' spécifie l'invite, qui doit être comprise entre $ 'et' pour laisser des espaces et des caractères d'échappement. Attention, vous devez mettre entre guillemets simples avec le symbole dollars pour bénéficier des caractères échappés, sinon vous pouvez utiliser des guillemets simples.

-d $ ' \ e ' spécifie escappe comme caractère de délimitation, donc comme caractère final pour l'entrée courante, il est possible de mettre n'importe quel caractère mais attention à mettre un caractère que l'utilisateur peut taper.

-n 1 spécifie qu'il n'a besoin que d'un seul caractère.

-e spécifie le mode de ligne de lecture.

-i $ ' Y ' spécifie Y comme texte initial en mode readline.

-t 5 spécifie un délai d'expiration de 5 secondes

touche servir au cas où vous auriez besoin de connaître l'entrée, dans le cas -n1, la touche qui a été pressée.

$? servir à connaître le code de sortie du dernier programme, pour lecture, 142 en cas de timeout, 0 entrée correcte. Mettez $? dans une variable dès que possible si vous avez besoin de la tester après quelques commandes, car toutes les commandes réécriraient $?

y.petremann
la source
1
+1 pour expliquer -s; man readet l' read --helpaide n'a pas aidé sur Ubuntu 10.04.1 LTS. Edit: help readdid; le reste est-il déconseillé?
Cees Timmerman
1
1+ pour la grande explication: mais j'ai eu read: -i: invalid optionpour l'ex. read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;sur #osx read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key;fonctionne pour moi à la place. `
Tino Rüb
Je ne sais pas comment cela fonctionne sur OSX mais j'ai fait quelques tests et -ifonctionne parfaitement sur Ubuntu, je ne sais pas non plus comment cela -dfonctionne de la même manière sur OSX.
y.petremann
on peut contourner l'invite très rapidement et agréablement en utilisant un écho avant lecture, éventuellement echo -n
THESorcerer
15

readsans aucun paramètre ne continuera que si vous appuyez sur Entrée. La pausecommande DOS continuera si vous appuyez sur n'importe quelle touche. À utiliser read –n1si vous souhaitez ce comportement.

xsl
la source
15

Cela a fonctionné pour moi sur plusieurs versions de Linux, où certaines de ces autres solutions ne fonctionnaient pas (y compris les plus populaires ici). Je pense que c'est aussi plus lisible ...

echo Press enter to continue; read dummy;

Notez qu'une variable doit être fournie comme argument à read.

BuvinJ
la source
cette réponse résout mon problème, si je copie et colle cette ligne et pour une raison quelconque, j'ai ajouté plus de lignes, les lignes ajoutées ne sont pas exécutées, comme c'était le cas avec la pause DOS
Sérgio
10

read -n1n'est pas portable. Une façon portable de faire de même pourrait être:

(   trap "stty $(stty -g;stty -icanon)" EXIT
    LC_ALL=C dd bs=1 count=1 >/dev/null 2>&1
)   </dev/tty

En plus d'utiliser read, pour juste une pression sur ENTERpour continuer, vous pouvez faire:

sed -n q </dev/tty
mikeserv
la source
2
status=nonen'est pas portable non plus. Redirigez plutôt stdout et stderr vers / dev / null. read -r line < /dev/ttyserait enought pour appuyer sur ENTRER ... .
Stephane Chazelas
@StephaneChezales merci - je ne le savais pas. mal le réparer maintenant. Merci encore - corrigé. Soit dit en passant, un puits sans fond d'informations utiles.
mikeserv
1
Notez également le settings=$(stty -g); stty raw; dd ...; stty "$settings"pour enregistrer et restaurer les paramètres tty.
Stéphane Chazelas
@StephaneChezales - je ne suis pas devant un ordinateur - pensez-vous que la fonction d' trédition pourrait également fonctionner?
mikeserv
1
Non, car trcela tamponnerait sa sortie comme un canal, et les claviers non américains ont des touches qui envoient des caractères en dehors de la \1-\177plage. ddest la voie idiomatique ici.
Stephane Chazelas
2

Si vous avez juste besoin de suspendre une boucle ou un script, et que vous êtes heureux d'appuyer sur Entrée au lieu d'une touche, alors readà lui seul fera le travail.

do_stuff
read
do_more_stuff

Il n'est pas convivial pour l'utilisateur final, mais peut être suffisant dans les cas où vous écrivez un script rapide pour vous-même, et vous devez le mettre en pause pour faire quelque chose manuellement en arrière-plan.

mwfearnley
la source
C'est vrai, mais pour la base de données, il est très utile de montrer un exemple.
SDsolar
Merci, j'ai pris en compte vos conseils. L'écriture d'un nom de commande n'est pas très claire avec le recul.
mwfearnley
1

Essaye ça:

function pause(){
   read -p "$*"
}
Alex Fort
la source
1
Quelqu'un peut-il expliquer pourquoi cela est rejeté? Est-ce par manque de contenu ou est-ce une mauvaise solution?
3ocene
4
@ 3ocene Ceci n'indique pas l'utilisation de la fonction qui est créée; plus ce manque aucune explication.
parvus
D'accord. Pouvez-vous s'il vous plaît montrer un exemple de la façon dont cette fonction est invoquée?
SDsolar
1

Cette fonction fonctionne à la fois sur bashet zshet 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}shrcfor Great Justice!

Tom Hale
la source
0

Oui à l'utilisation read- et il y a quelques réglages qui le rendent plus utile à la fois cronet dans le terminal.

Exemple:

time rsync (options)
read -n 120 -p "Press 'Enter' to continue..." ; echo " "

Le -n 120 fait expirer l'instruction de lecture après 2 minutes afin qu'il ne se bloque pas cron.

Dans le terminal, il donne 2 minutes pour voir combien de temps la rsynccommande a pris pour s'exécuter.

Ensuite, le suivant echoest donc l'invite bash suivante apparaîtra sur la ligne suivante.

Sinon, il s'affichera sur la même ligne directement après "continuer ..." lorsque vous Enterappuyez sur dans le terminal.

SDsolar
la source