GNU/Linux >> Tutoriales Linux >  >> Linux

¿Tiempo de espera agotado en un script de Shell?

Tengo un script de shell eso es leer desde una entrada estándar . En raras circunstancias, no habrá nadie listo para proporcionar información y el script debe tiempo de espera. . En caso de tiempo de espera, el script debe ejecutar algún código de limpieza. ¿Cuál es la mejor manera de hacerlo?

Este script debe ser muy portátil , incluidos los sistemas Unix del siglo XX sin un compilador C y los dispositivos integrados que ejecutan busybox, por lo que no se puede confiar en Perl, bash, ningún lenguaje compilado e incluso el POSIX.2 completo. En particular, $PPID , read -t y las trampas perfectamente compatibles con POSIX no están disponibles. También se excluye escribir en un archivo temporal; el script puede ejecutarse incluso si todos los sistemas de archivos están montados como de solo lectura.

Solo para hacer las cosas más difíciles, también quiero que el guión sea razonablemente rápido cuando no se agote el tiempo. En particular, también uso el script en Windows (principalmente en Cygwin), donde la bifurcación y la ejecución son particularmente bajas, por lo que quiero mantener su uso al mínimo.

En pocas palabras, tengo

trap cleanup 1 2 3 15
foo=`cat`

y quiero agregar un tiempo de espera. No puedo reemplazar cat con el read incorporado. En caso de tiempo de espera, quiero ejecutar cleanup función.

Antecedentes:este script adivina la codificación del terminal imprimiendo algunos caracteres de 8 bits y comparando la posición del cursor antes y después. El comienzo de la secuencia de comandos prueba que stdout está conectado a un terminal compatible, pero a veces el entorno miente (por ejemplo, plink establece TERM=xterm incluso si se llama con TERM=dumb ). La parte relevante del script se ve así:

text='Éé'  # UTF-8; shows up as Ãé on a latin1 terminal
csi='␛['; dsr_cpr="${csi}6n"; dsr_ok="${csi}5n"  # ␛ is an escape character
stty_save=`stty -g`
cleanup () { stty "$stty_save"; }
trap 'cleanup; exit 120' 0 1 2 3 15     # cleanup code
stty eol 0 eof n -echo                # Input will end with `0n`
# echo-n is a function that outputs its argument without a newline
echo-n "$dsr_cpr$dsr_ok"              # Ask the terminal to report the cursor position
initial_report=`tr -dc ;0123456789`  # Expect ␛[42;10R␛[0n for y=42,x=10
echo-n "$text$dsr_cpr$dsr_ok"
final_report=`tr -dc ;0123456789`
cleanup
# Compute and return initial_x - final_x

¿Cómo puedo modificar el script para que si tr no ha leído ninguna entrada después de 2 segundos, se elimina y el script ejecuta la cleanup función?

Respuesta aceptada:

¿Qué pasa con esto:

foo=`{ { cat 1>&3; kill 0; } | { sleep 2; kill 0; } } 3>&1`

Es decir:ejecute el comando de producción de salida y sleep en el mismo grupo de procesos, un grupo de procesos solo para ellos. Cualquiera que sea el comando que regresa primero, mata todo el grupo de procesos.

Alguien se preguntaría:Sí, la tubería no se usa; se omite usando las redirecciones. El único propósito es que el shell ejecute los dos procesos en el mismo grupo de procesos.

Relacionado:¿Un script para reducir y comprimir imágenes de disco DMG no parece funcionar bien en el escenario?

Como señaló Gilles en su comentario, esto no funcionará en un script de shell porque el proceso del script se eliminaría junto con los dos subprocesos.

Una forma¹ de forzar la ejecución de un comando en un grupo de procesos separado es iniciar un nuevo shell interactivo:

#!/bin/sh
foo=`sh -ic '{ cat 1>&3; kill 0; } | { sleep 2; kill 0; }' 3>&1 2>/dev/null`
[ -n "$foo" ] && echo got: "$foo" || echo timeouted

Pero puede haber advertencias con esto (por ejemplo, ¿cuándo stdin no es un tty?). La redirección stderr está ahí para deshacerse del mensaje "Terminado" cuando se elimina el shell interactivo.

Probado con zsh ,bash y dash . Pero ¿qué pasa con los viejos?

B98 sugiere el siguiente cambio, trabajando en Mac OS X, con GNU bash 3.2.57 o Linux con guión:

foo=`sh -ic 'exec 3>&1 2>/dev/null; { cat 1>&3; kill 0; } | { sleep 2; kill 0; }'`



Linux
  1. ¿Determinar la ruta al script de Shell de origen?

  2. ¿Cómo manejar los interruptores en un script de Shell?

  3. ¿Comportamiento inesperado de un script de Shell?

  4. ¿Cómo crear un archivo temporal en Shell Script?

  5. ¿Ocultar la contraseña en los scripts de Shell?

Cómo usar variables en secuencias de comandos de Shell

Cómo crear scripts de shell

¿Determinar Shell en el script durante el tiempo de ejecución?

¿Cómo ejecutar un comando en un script de Shell?

determinar shell en el script durante el tiempo de ejecución

Ejecute un script de shell como un usuario diferente