He escrito un script de shell para probar una API que copia archivos y hace eco de su progreso después de cada uno.
Hay una suspensión de dos segundos entre cada copia, por lo que me gustaría agregar la capacidad de presionar cualquier tecla para pausar el script y permitir una prueba más profunda. Luego presione cualquier tecla para reanudar.
¿Cómo puedo agregar esto en la menor cantidad de líneas posible?
shell-script
blarg
fuente
fuente
sleep 10; notify-send hello
y presiono CTRL + Z para detener,notify-send hello
me ejecutan. si se ejecuta el segundo comando, ¿cómo se detiene el primer proceso? después de eso si el tipofg
no puedo ver que ocurra algo, lo cual es obvio, ya que el segundo comando ya está ejecutadocmd; cmd; cmd;
es como escribircmd <newline> cmd <newline> ...
. Como alternativa a una secuencia de comandos puede escribir( cmd; cmd; cmd; )
, que se comportaría como el guión, bacuse del subnivel generada por(
sleep 10
. cuando presiono CTRL + Z después de 3 segundos y reanudo después de unos segundos y noté que el comando de suspensión murió en menos de 7 segundos. que es opuesto a lo que dijiste, ya que el comando nunca se detiene, simplemente se ejecuta en segundo plano.strace
D delsleep
mando y descubrí que la llamada al sistema utilizado esnanosleep()
. Parece ser un comportamiento definido de lananosleep
llamada al sistema.restart_syscall()
reinicia la llamada interrumpida del sistema con un argumento de tiempo que se ajusta adecuadamente para tener en cuenta el tiempo que ya ha transcurrido (incluido el tiempo en que el proceso fue detenido por una señal). Lea esa página de manualfg %1
:) o en el fondo (ejbg %1
.:). (si los trabajos solo dan 1 número, es decir, solo 1 proceso suspendido, como se muestra en el ejemplo de caos: solo[1]+ stopped sleep 10
, puede omitir la%n
parte. Si hay varios procesos en segundo plano (en ejecución o detenidos), debe designar el que desea con:%n
(por ejemplo:fg %2
tener% 2 currículum en primer plano))Si solo desea pausar el guión mientras permanece dentro del guión, puede usar leer en lugar de dormir.
Puedes usar
read -t
para establecer un tiempo de espera para que la lecturaread -n
lea un carácter (efectivamente, simplemente presione cualquier tecla) para continuar la secuencia de comandosComo no ha proporcionado ningún código, a continuación se muestra un ejemplo de cómo podría usarse.
Si se presiona q, entonces
read -n1
evita que el script continúe hasta que se presiona una tecla.Cuando se presiona una tecla, la verificación se restablece y el script continúa en el bucle como de costumbre.
También puede agregar
stty -echo
al inicio de la sección ystty echo
al final para evitar que la escritura estropee la salida de la pantallafuente
Con
dd
usted puede leer de manera confiable un solo byte de un archivo. Constty
usted puede establecer unmin
número de bytes para calificar una lectura de terminal y unatime
salida en décimas de segundo. Combina esos dos y puedes prescindir porsleep
completo, creo, y solo deja que el tiempo de espera de lectura del terminal haga el trabajo por ti:Ese es un pequeño
while
bucle de ejemplo que me burlé para que lo pruebes. Cada dos segundosdd
agota su intento de lectura destdin
- redirigido desde/dev/tty
- y loswhile
bucles de bucle. Eso odd
no expira porque presiona una tecla, en cuyo caso se invoca un shell interactivo.Aquí hay una prueba de funcionamiento: los números impresos en la cabecera de cada línea son el valor de la variable de shell
$SECONDS
:fuente
stty sane
después de cambiar la configuración stty, puedo estar equivocado pero no parece que los reinicies en ningún lado?s=$(stty -g </dev/tty)
. Inmediatamente después de llamar,dd
lo restauro constty "$s"
. El estado del terminal no se preocupa por las subcapas y, por lo tanto, esas configuraciones se mantienen independientemente del shell principal.stty sane
no es necesariamente lo que quieres hacer: es mejor restaurar el estado a la forma en que lo encontraste que asumir que el estado estabasane
en ese punto. Si no lo restaurara, esoecho
estaría por todas partes. Entender eso es en parte por qué llegué tan tarde: su respuesta no estaba aquí cuando comencé a probar.