tail
non si blocca
Come sempre:per ogni cosa c'è una risposta breve, facile da capire, facile da seguire e completamente sbagliata. Qui tail -f /dev/null
rientra in questa categoria;)
Se lo guardi con strace tail -f /dev/null
noterai che questa soluzione è tutt'altro che bloccante! Probabilmente è anche peggio del sleep
soluzione nella domanda, poiché utilizza (sotto Linux) risorse preziose come inotify
sistema. Anche altri processi che scrivono in /dev/null
crea tail
ciclo continuo. (Sul mio Ubuntu64 16.10 questo aggiunge diverse 10 chiamate di sistema al secondo su un sistema già occupato.)
La domanda era per un comando di blocco
Sfortunatamente, non esiste una cosa del genere ..
Leggi:non conosco alcun modo per archiviarlo direttamente con la shell.
Tutto (anche sleep infinity
) può essere interrotto da qualche segnale. Quindi, se vuoi essere veramente sicuro che non ritorni eccezionalmente, deve essere eseguito in un ciclo, come hai già fatto per il tuo sleep
. Si prega di notare che (su Linux) /bin/sleep
apparentemente è limitato a 24 giorni (dai un'occhiata a strace sleep infinity
), quindi il meglio che puoi fare probabilmente è:
while :; do sleep 2073600; done
(Nota che credo sleep
si ripete internamente per valori superiori a 24 giorni, ma ciò significa:non si blocca, si ripete molto lentamente. Allora perché non spostare questo loop all'esterno?)
.. ma puoi avvicinarti abbastanza con un fifo
senza nome
Puoi creare qualcosa che blocchi davvero fintanto che non ci sono segnali inviati al processo. Seguire usa bash 4
, 2 PID e 1 fifo
:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
Puoi controllare che questo si blocchi davvero con strace
se ti piace:
strace -ff bash -c '..see above..'
Come è stato costruito
read
blocca se non ci sono dati di input (vedi alcune altre risposte). Tuttavia, il tty
(ovvero stdin
) di solito non è una buona fonte, poiché viene chiuso quando l'utente si disconnette. Inoltre potrebbe rubare qualche input dal tty
. Non carino.
Per fare read
block, dobbiamo aspettare qualcosa come un fifo
che non restituirà mai nulla. In bash 4
c'è un comando che può fornirci esattamente un tale fifo
:coproc
. Se aspettiamo anche il blocco read
(che è il nostro coproc
), abbiamo chiuso. Purtroppo questo deve mantenere aperti due PID e un fifo
.
Variante con nome fifo
Se non ti preoccupi di usare un nome fifo
, puoi farlo come segue:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
Non usare un loop durante la lettura è un po' approssimativo, ma puoi riutilizzare questo fifo
tutte le volte che vuoi e fai il read
s termina usando touch "$HOME/.pause.fifo"
(se c'è più di una singola lettura in attesa, tutte vengono terminate in una volta).
Oppure usa Linux pause()
chiamata di sistema
Per il blocco infinito c'è una chiamata al kernel Linux, chiamata pause()
, che fa quello che vogliamo:Aspetta per sempre (fino all'arrivo di un segnale). Tuttavia non esiste (ancora) un programma in spazio utente per questo.
C
Creare un tale programma è facile. Ecco uno snippet per creare un programma Linux molto piccolo chiamato pause
che si ferma indefinitamente (richiede diet
, gcc
ecc.):
printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause
python
Se non vuoi compilare qualcosa da solo, ma hai python
installato, puoi usarlo sotto Linux:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Nota:usa exec python -c ...
per sostituire la shell corrente, questo libera un PID. La soluzione può essere migliorata anche con alcuni reindirizzamenti IO, liberando FD inutilizzati. Dipende da te.)
Come funziona (credo):ctypes.CDLL(None)
carica la libreria C standard ed esegue il pause()
funzione in esso all'interno di un ciclo aggiuntivo. Meno efficiente della versione C, ma funziona.
Il mio consiglio per te:
Rimani al sonno in loop. È facile da capire, molto portatile e blocca la maggior parte del tempo.
sleep infinity
fa esattamente quello che suggerisce e funziona senza abusi sui gatti.