tail
non blocca
Come sempre: per ogni cosa c'è una risposta che è breve, facile da capire, facile da seguire e completamente sbagliata. Qui tail -f /dev/null
rientra in questa categoria;)
Se lo guardi strace tail -f /dev/null
noterai che questa soluzione è lungi dall'essere bloccata! Probabilmente è anche peggio delsleep
soluzione nella domanda, poiché utilizza (sotto Linux) risorse preziose come il inotify
sistema. Anche altri processi che scrivono per /dev/null
faretail
loop. (Sul mio Ubuntu64 16.10 questo aggiunge diverse 10 syscall al secondo su un sistema già occupato.)
La domanda era per un comando di blocco
Sfortunatamente, non esiste nulla del genere ..
Leggi: Non conosco alcun modo per archiviare questo direttamente con la shell.
Tutto (anche sleep infinity
) può essere interrotto da qualche segnale. Quindi, se vuoi essere davvero sicuro che non ritorni eccezionalmente, deve essere eseguito in un ciclo, come hai già fatto per il tuo sleep
. Si noti che (su Linux) /bin/sleep
apparentemente è limitato a 24 giorni (dai un'occhiata strace sleep infinity
), quindi il meglio che puoi fare probabilmente è:
while :; do sleep 2073600; done
(Nota che credo sleep
cicli internamente per valori più alti di 24 giorni, ma questo significa: non si blocca, è in loop molto lentamente. Quindi perché non spostare questo loop verso l'esterno?)
.. ma puoi avvicinarti abbastanza con un senza nome fifo
Puoi creare qualcosa che si blocchi davvero fintanto che non ci sono segnali inviati al processo. A seguito di usi bash 4
, 2 PID e 1 fifo
:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
Puoi verificare che questo si blocchi davvero 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
(aka. stdin
) Di solito non è una buona fonte, poiché viene chiuso quando l'utente si disconnette. Inoltre potrebbe rubare alcuni input dal tty
. Non bello.
Per read
bloccare, dobbiamo aspettare qualcosa come un fifo
che non restituirà mai nulla. In bash 4
c'è un comando che può esattamente fornirci una tale fifo
: coproc
. Se aspettiamo anche il blocco read
(che è il nostro coproc
), abbiamo finito. Purtroppo questo deve tenere aperti due PID e afifo
.
Variante con un 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 ciclo sulla lettura è un po 'sciatto, ma puoi riutilizzarlo tutte fifo
le volte che vuoi e fare read
terminare la s usando touch "$HOME/.pause.fifo"
(se ci sono più di una sola lettura in attesa, tutte sono terminate contemporaneamente).
Oppure usa il pause()
syscall di Linux
Per il blocco infinito c'è una chiamata al kernel Linux, chiamata pause()
, che fa quello che vogliamo: attendere per sempre (fino all'arrivo di un segnale). Tuttavia non esiste un programma di spazio utente per questo (ancora).
C
Creare un programma del genere è facile. Ecco uno snippet per creare un programma Linux molto piccolo chiamato pause
che fa una pausa indefinitamente (esigenze 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 te, ma hai python
installato, puoi usarlo sotto Linux:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Nota: utilizzare exec python -c ...
per sostituire la shell corrente, questo libera un PID. La soluzione può essere migliorata anche con un po 'di reindirizzamento IO, liberando FD inutilizzati. Dipende da te.)
Come funziona (penso): ctypes.CDLL(None)
carica la libreria C standard ed esegue la pause()
funzione in essa all'interno di un ciclo aggiuntivo. Meno efficiente della versione C, ma funziona.
La mia raccomandazione per te:
Resta nel sonno continuo. È facile da capire, molto portatile e si blocca per la maggior parte del tempo.