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/nullrientra in questa categoria;)
Se lo guardi strace tail -f /dev/nullnoterai che questa soluzione è lungi dall'essere bloccata! Probabilmente è anche peggio delsleep soluzione nella domanda, poiché utilizza (sotto Linux) risorse preziose come il inotifysistema. Anche altri processi che scrivono per /dev/nullfaretail 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/sleepapparentemente è 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 stracese ti piace:
strace -ff bash -c '..see above..'
Come è stato costruito
readblocca 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 readbloccare, dobbiamo aspettare qualcosa come un fifoche non restituirà mai nulla. In bash 4c'è 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 fifole volte che vuoi e fare readterminare 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 pauseche fa una pausa indefinitamente (esigenze diet, gccecc.):
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 pythoninstallato, 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.