¿Cuál es el equivalente de Linux a la pausa de DOS?

236

Tengo un script de shell Bash en el que me gustaría pausar la ejecución hasta que el usuario presione una tecla. En DOS, esto se logra fácilmente con el comando "pausa". ¿Hay un equivalente de Linux que pueda usar en mi script?

jt.
fuente

Respuestas:

329

read Haz esto:

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

Las -n1especifica que sólo espera a que un solo carácter. Lo -rpone en modo sin formato, lo cual es necesario porque de lo contrario, si presiona algo como la barra invertida, no se registrará hasta que presione la siguiente tecla. Las -pespecifica el indicador, que deberá indicarse si contiene espacios. El keyargumento solo es necesario si desea saber qué tecla presionaron, en cuyo caso puede acceder a ella $key.

Si está utilizando Bash, también puede especificar un tiempo de espera con -t, lo que hace que la lectura devuelva un error cuando no se presiona una tecla. Así por ejemplo:

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
fuente
55
Estrictamente hablando, eso sería "Enter any non-NUL character to continue". Algunas teclas no envían ningún carácter (como Ctrl...) y otras envían más de uno (como F1, Home...). bashignora los caracteres NUL.
Stephane Chazelas
2
Por lo general, es una mejor idea pedir una clave específica como enter, space o Y. "CUALQUIERA" puede ser confuso para algunos usuarios, hay una tecla TAB, entonces ¿por qué no CUALQUIER tecla y seguramente hay claves que son potencialmente peligrosas? como ESCAPE, CTRL, CMD, el botón de encendido, etc. Esto ya no es tan relevante hoy en día, porque hoy en día la consola solo es utilizada por usuarios avanzados de computadoras que interpretarán "CUALQUIER tecla" correctamente. El Manual de diseño de Apple 2, bastante antiguo, tiene una sección interesante dedicada a este tema ( apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf ).
Gellweiler
3
Si en su lugar usa el mensaje Press a key to continue..., incluso los usuarios novatos podrán encontrar la atecla y presionarla; o)
DJDaveMark
1
Esto tendrá problemas con command | myscript.sho myscript.sh | command. Vea esta respuesta para una solución.
Tom Hale
Si alguien se read: 1: read: Illegal option -nasegura, envuelva su comando en bash -c 'command && command'etc., ya que es probable que se produzca ese error sh. Estoy haciendo esto en un comando de contenedor Lando.
Elijah Lynn el
155

Utilizo mucho estas formas que son muy cortas, y son como las soluciones @theunamedguy y @Jim, pero con tiempo de espera y modo silencioso además.

Especialmente me encanta el último caso y lo uso en muchos scripts que se ejecutan en bucle hasta que el usuario presiona Enter.

Comandos

  • Introducir solución

    read -rsp $'Press enter to continue...\n'
  • Solución de escape (con -d $ '\ e')

    read -rsp $'Press escape to continue...\n' -d $'\e'
  • Cualquier solución clave (con -n 1)

    read -rsp $'Press any key to continue...\n' -n 1 key
    # echo $key
  • Pregunta con opción preseleccionada (con -ei $ 'Y')

    read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;
    # echo $key
  • Solución de tiempo de espera (con -t 5)

    read -rsp $'Press any key or wait 5 seconds to continue...\n' -n 1 -t 5;
  • Sueño mejorado alias

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

Explicación

-r especifica el modo sin formato, que no permite caracteres combinados como "\" o "^".

-s especifica el modo silencioso y porque no necesitamos salida de teclado.

-p $ ' prompt ' especifica la solicitud, que debe estar entre $ 'y' para dejar espacios y caracteres escapados. Tenga cuidado, debe poner entre comillas simples con el símbolo de dólares para beneficiar a los caracteres escapados, de lo contrario puede usar comillas simples.

-d $ ' \ e ' especifica escappe como delimitador de caracteres, por lo que, como carácter final para la entrada actual, es posible poner cualquier carácter, pero tenga cuidado de poner un carácter que el usuario pueda escribir.

-n 1 especifica que solo necesita un único carácter.

-e especifica el modo readline.

-i $ ' Y ' especifica Y como texto inicial en modo readline.

-t 5 especifica un tiempo de espera de 5 segundos

Tecla servir en caso de que necesite conocer la entrada, en el caso -n1, la tecla que se ha presionado.

PS sirven para conocer el código de salida del último programa, para leer, 142 en caso de tiempo de espera, 0 entrada correcta. Poner $? en una variable lo antes posible si necesita probarla después de algunos comandos, porque todos los comandos reescribirán $?

y.petremann
fuente
1
+1 para explicar -s; man ready la read --helpayuda no ayudó en Ubuntu 10.04.1 LTS. Editar: help readhizo; ¿El resto está en desuso?
Cees Timmerman
1
1+ por la gran explicación: pero obtuve read: -i: invalid optionpor el ex. read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;en #osx read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key;funciona para mí en su lugar. `
Tino Rüb
No sé cómo funciona en OSX, pero he hecho algunas pruebas y -ifunciona perfectamente en Ubuntu, tampoco sé cómo -dfunciona de la misma manera en OSX.
y.petremann
uno puede evitar el aviso realmente rápido y agradable mediante el uso de un eco antes de leer, eventualmente echo -n
THESorcerer
15

readsin ningún parámetro solo continuará si presiona enter. El pausecomando DOS continuará si presiona cualquier tecla. Úselo read –n1si desea este comportamiento.

xsl
fuente
15

Esto funcionó para mí en múltiples versiones de Linux, donde algunas de estas otras soluciones no lo hicieron (incluidas las más populares aquí). Creo que también es más legible ...

echo Press enter to continue; read dummy;

Tenga en cuenta que se debe proporcionar una variable como argumento para read.

BuvinJ
fuente
esta respuesta resuelve mi problema, si copio y pego esta línea y por alguna razón tengo más líneas agregadas, las líneas adjuntas no se ejecutan, como ocurrió con la pausa de DOS
Sérgio
10

read -n1No es portátil. Una forma portátil de hacer lo mismo podría ser:

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

Además de usar read, solo por presionar ENTERpara continuar, puede hacer lo siguiente:

sed -n q </dev/tty
mikeserv
fuente
2
status=nonetampoco es portátil. Redirige stdout y stderr a / dev / null en su lugar. read -r line < /dev/ttysería lo suficientemente para pulsar ENTER ... .
Stephane Chazelas
@StephaneChezales gracias, no lo sabía. Lo arreglaré ahora. Gracias de nuevo, arreglado. Por cierto, eres un pozo sin fondo de información valiosa.
mikeserv
1
También tenga en cuenta que settings=$(stty -g); stty raw; dd ...; stty "$settings"para guardar y restaurar la configuración de tty.
Stephane Chazelas
@StephaneChezales, no estoy en una computadora, ¿crees que la tredición también podría funcionar?
mikeserv
1
No, porque tramortiguaría su salida como una tubería, y los teclados no estadounidenses tienen teclas que envían caracteres fuera del \1-\177rango. ddEs la manera idiomática aquí.
Stephane Chazelas
2

Si solo necesita pausar un bucle o secuencia de comandos, y está feliz de presionar Enter en lugar de cualquier tecla, entonces readpor sí solo hará el trabajo.

do_stuff
read
do_more_stuff

No es fácil de usar para el usuario final, pero puede ser suficiente en los casos en que está escribiendo un script rápido para usted y necesita pausarlo para hacer algo manualmente en segundo plano.

mwfearnley
fuente
Esto es cierto, pero para la base de datos es más útil mostrar un ejemplo.
SDsolar
Gracias, tomé tu consejo a bordo. Simplemente escribir un nombre de comando no es muy claro en retrospectiva.
mwfearnley
1

Prueba esto:

function pause(){
   read -p "$*"
}
Alex Fort
fuente
1
¿Alguien puede explicar por qué esto se rechaza? ¿Es por falta de contenido o es una mala solución?
3oceno
44
@ 3ocene Esto no muestra el uso de la función que se crea; Además de esto falta alguna explicación.
parvus
Convenido. ¿Puede mostrar un ejemplo de cómo se invoca esta función?
SDsolar
1

Esta función funciona en ambos bashy zsh, y asegura E / S al 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

¡Ponlo en tu .{ba,z}shrcpara Gran Justicia!

Tom Hale
fuente
0

Sí al uso read, y hay un par de ajustes que lo hacen más útil tanto cronen el terminal como en el terminal.

Ejemplo:

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

El -n 120 hace que la instrucción de lectura termine el tiempo de espera después de 2 minutos para que no se bloquee cron.

En la terminal, da 2 minutos para ver cuánto tiempo rsynctardó en ejecutarse el comando.

Luego, lo siguiente echoes para que aparezca el indicador de bash posterior en la siguiente línea.

De lo contrario, se mostrará en la misma línea directamente después de "continuar ..." cuando Enterse presiona en el terminal.

SDsolar
fuente