GNU/Linux >> Tutoriales Linux >  >> Linux

Bash:sueño infinito (bloqueo infinito)

tail no bloquea

Como siempre:Para todo hay una respuesta que es breve, fácil de entender, fácil de seguir y completamente incorrecta. Aquí tail -f /dev/null entra en esta categoría;)

Si lo miras con strace tail -f /dev/null ¡notará que esta solución está lejos de bloquear! Probablemente sea incluso peor que el sleep solución en la pregunta, ya que utiliza (bajo Linux) recursos preciosos como el inotify sistema. También otros procesos que escriben en /dev/null hacer tail círculo. (En mi Ubuntu64 16.10, esto agrega varias 10 llamadas al sistema por segundo en un sistema que ya está ocupado).

La pregunta era por un comando de bloqueo

Desafortunadamente, no existe tal cosa...

Leer:No conozco ninguna forma de archivar esto directamente con el shell.

Todo (incluso sleep infinity ) puede ser interrumpido por alguna señal. Entonces, si quiere estar realmente seguro de que no regresa excepcionalmente, debe ejecutarse en un bucle, como ya lo hizo para su sleep . Tenga en cuenta que (en Linux) /bin/sleep aparentemente tiene un límite de 24 días (echa un vistazo a strace sleep infinity ), por lo tanto, lo mejor que puede hacer probablemente sea:

while :; do sleep 2073600; done

(Tenga en cuenta que creo sleep se repite internamente para valores superiores a 24 días, pero esto significa:No se bloquea, se repite muy lentamente. Entonces, ¿por qué no mover este bucle hacia afuera?)

... pero puedes acercarte bastante con un fifo sin nombre

Puede crear algo que realmente bloquee siempre que no se envíen señales al proceso. Los siguientes usos bash 4 , 2 PID y 1 fifo :

bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'

Puedes comprobar que esto realmente bloquea con strace si te gusta:

strace -ff bash -c '..see above..'

Cómo se construyó esto

read bloques si no hay datos de entrada (ver algunas otras respuestas). Sin embargo, el tty (también conocido como stdin ) por lo general no es una buena fuente, ya que se cierra cuando el usuario cierra la sesión. También podría robar alguna entrada del tty . No es agradable.

Para hacer read bloque, tenemos que esperar algo como un fifo que nunca devolverá nada. En bash 4 hay un comando que exactamente puede proporcionarnos tal fifo :coproc . Si también esperamos el bloqueo read (que es nuestro coproc ), hemos terminado. Lamentablemente, esto debe mantener abiertos dos PID y un fifo .

Variante con un fifo con nombre

Si no se molesta en usar un fifo con nombre , puede hacerlo de la siguiente manera:

mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"

No usar un bucle en la lectura es un poco descuidado, pero puedes reutilizar este fifo tantas veces como quieras y haz el read s termina usando touch "$HOME/.pause.fifo" (si hay más de una sola lectura en espera, todas se terminan a la vez).

O use Linux pause() llamada al sistema

Para el bloqueo infinito hay una llamada al kernel de Linux, llamada pause() , que hace lo que queremos:Esperar para siempre (hasta que llegue una señal). Sin embargo, no existe un programa de espacio de usuario para esto (todavía).

C

Crear un programa de este tipo es fácil. Aquí hay un fragmento para crear un programa Linux muy pequeño llamado pause que se detiene indefinidamente (necesita diet , gcc etc.):

printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause

python

Si no quiere compilar algo usted mismo, pero tiene python instalado, puede usar esto bajo Linux:

python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'

(Nota:utilice exec python -c ... para reemplazar el shell actual, esto libera un PID. La solución también se puede mejorar con alguna redirección de E/S, liberando FD no utilizados. Esto depende de ti).

Cómo funciona esto (creo):ctypes.CDLL(None) carga la biblioteca C estándar y ejecuta el pause() funcionar en él dentro de algún bucle adicional. Menos eficiente que la versión C, pero funciona.

Mi recomendación para ti:

Quédate en el sueño en bucle. Es fácil de entender, muy portátil y bloquea la mayor parte del tiempo.


sleep infinity hace exactamente lo que sugiere y funciona sin maltratar a los gatos.


Linux
  1. Bash secuencias de comandos (I)

  2. Usando el comando de suspensión de Linux en Bash Scripts

  3. Ordenando en bash

  4. comando de exportación bash

  5. Ejecute el comando bash en la canalización de jenkins

Comando de suspensión de Linux (Pausar un script Bash)

Declaración de Bash if..else

Arreglos bash

Bash Shebang

Comando Bash printf

Matriz asociativa en Bash