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 helloy presiono CTRL + Z para detener,notify-send hellome ejecutan. si se ejecuta el segundo comando, ¿cómo se detiene el primer proceso? después de eso si el tipofgno 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.straceD delsleepmando y descubrí que la llamada al sistema utilizado esnanosleep(). Parece ser un comportamiento definido de lananosleepllamada 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%nparte. Si hay varios procesos en segundo plano (en ejecución o detenidos), debe designar el que desea con:%n(por ejemplo:fg %2tener% 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 -tpara establecer un tiempo de espera para que la lecturaread -nlea 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 -n1evita 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 -echoal inicio de la sección ystty echoal final para evitar que la escritura estropee la salida de la pantallafuente
Con
ddusted puede leer de manera confiable un solo byte de un archivo. Consttyusted puede establecer unminnúmero de bytes para calificar una lectura de terminal y unatimesalida en décimas de segundo. Combina esos dos y puedes prescindir porsleepcompleto, creo, y solo deja que el tiempo de espera de lectura del terminal haga el trabajo por ti:Ese es un pequeño
whilebucle de ejemplo que me burlé para que lo pruebes. Cada dos segundosddagota su intento de lectura destdin- redirigido desde/dev/tty- y loswhilebucles de bucle. Eso oddno 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 sanedespué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,ddlo 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 saneno es necesariamente lo que quieres hacer: es mejor restaurar el estado a la forma en que lo encontraste que asumir que el estado estabasaneen ese punto. Si no lo restaurara, esoechoestaría por todas partes. Entender eso es en parte por qué llegué tan tarde: su respuesta no estaba aquí cuando comencé a probar.