tail
no bloquea
Como siempre: para todo hay una respuesta que es corta, fácil de entender, fácil de seguir y completamente errónea. Aquí tail -f /dev/null
entra en esta categoría;)
Si lo mira con strace tail -f /dev/null
atención, notará que esta solución está lejos de bloquearse. Probablemente sea incluso peor que la sleep
solución en la pregunta, ya que utiliza (bajo Linux) recursos preciosos como el inotify
sistema. También otros procesos que escriben para /dev/null
hacer un tail
bucle. (En mi Ubuntu64 16.10 esto agrega varias 10 llamadas al sistema por segundo en un sistema que ya está ocupado).
La pregunta era para un comando de bloqueo
Lamentablemente, no existe tal cosa ...
Leer: No conozco ninguna forma de archivar esto con el shell directamente.
Todo (incluso sleep infinity
) puede ser interrumpido por alguna señal. Entonces, si desea 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 (eche un vistazo strace sleep infinity
), por lo tanto, lo mejor que puede hacer es:
while :; do sleep 2073600; done
(Tenga en cuenta que creo que los sleep
bucles internos para valores superiores a 24 días, pero esto significa: no está bloqueando, está haciendo un bucle muy lento. Entonces, ¿por qué no mover este bucle al exterior?)
.. pero puedes acercarte bastante con un nombre sin nombre fifo
Puede crear algo que realmente bloquee siempre que no se envíen señales al proceso. 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 strace
si quieres:
strace -ff bash -c '..see above..'
Cómo se construyó esto
read
bloquea si no hay datos de entrada (ver algunas otras respuestas). Sin embargo, el tty
(alias stdin
) generalmente no es una buena fuente, ya que se cierra cuando el usuario cierra sesión. También podría robar alguna información del tty
. No está bien.
Para hacer un read
bloqueo, debemos esperar algo como algo fifo
que nunca devolverá nada. En bash 4
existe un comando que exactamente nos puede dar un ejemplo fifo
: coproc
. Si también esperamos el bloqueo read
(que es nuestro coproc
), hemos terminado. Lamentablemente, esto debe mantener abiertos dos PID y a fifo
.
Variante con un nombre fifo
Si no te molestas en usar un nombre fifo
, puedes 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 puede reutilizarlo tantas fifo
veces como lo desee y hacer que el read
s termine usando touch "$HOME/.pause.fifo"
(si hay más de una sola lectura en espera, todas se terminan a la vez).
O use el pause()
syscall de Linux
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 hay un programa de espacio de usuario para esto (todavía).
C
Crear un programa así es fácil. Aquí hay un fragmento para crear un programa Linux muy pequeño llamado pause
que se detiene indefinidamente (necesidades 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 desea compilar algo usted mismo, pero lo ha python
instalado, puede usar esto en Linux:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Nota: se usa exec python -c ...
para reemplazar el shell actual, esto libera un PID. La solución se puede mejorar también con alguna redirección de E / S, liberando FD no utilizados. Esto depende de usted).
Cómo funciona esto (creo): ctypes.CDLL(None)
carga la biblioteca C estándar y ejecuta la pause()
función dentro de un 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.