tail
ne bloque pas
Comme toujours: pour tout, il y a une réponse courte, facile à comprendre, facile à suivre et complètement fausse. Entre ici tail -f /dev/null
dans cette catégorie;)
Si vous le regardez avec strace tail -f /dev/null
vous, vous remarquerez que cette solution est loin d'être bloquante! C'est probablement encore pire que la sleep
solution de la question, car elle utilise (sous Linux) des ressources précieuses comme le inotify
système. Aussi d'autres processus qui écrivent pour /dev/null
faire une tail
boucle. (Sur mon Ubuntu64 16.10, cela ajoute plusieurs 10 appels système par seconde sur un système déjà occupé.)
La question était pour une commande de blocage
Malheureusement, une telle chose n'existe pas.
Lire: Je ne connais aucun moyen d'archiver cela directement avec le shell.
Tout (même sleep infinity
) peut être interrompu par un signal. Donc, si vous voulez être vraiment sûr qu'il ne revient pas exceptionnellement, il doit s'exécuter en boucle, comme vous l'avez déjà fait pour votre sleep
. Veuillez noter que (sous Linux) /bin/sleep
est apparemment plafonné à 24 jours (jetez un œil à strace sleep infinity
), donc le mieux que vous puissiez faire est probablement:
while :; do sleep 2073600; done
(Notez que je crois que les sleep
boucles en interne pour des valeurs supérieures à 24 jours, mais cela signifie: ce n'est pas un blocage, c'est une boucle très lente. Alors pourquoi ne pas déplacer cette boucle vers l'extérieur?)
.. mais vous pouvez vous en approcher avec un nom sans nom fifo
Vous pouvez créer quelque chose qui bloque vraiment tant qu'aucun signal n'est envoyé au processus. Utilisations suivantes bash 4
, 2 PID et 1 fifo
:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
Vous pouvez vérifier que cela bloque vraiment avec strace
si vous aimez:
strace -ff bash -c '..see above..'
Comment cela a été construit
read
bloque s'il n'y a pas de données d'entrée (voir quelques autres réponses). Cependant, le tty
(aka. stdin
) N'est généralement pas une bonne source, car il est fermé lorsque l'utilisateur se déconnecte. En outre, il pourrait voler une contribution du tty
. Pas gentil.
Pour faire un read
bloc, nous devons attendre quelque chose comme un fifo
qui ne retournera jamais rien. En bash 4
il y a une commande qui peut exactement nous fournir un tel fifo
: coproc
. Si nous attendons également le blocage read
(qui est le nôtre coproc
), nous avons terminé. Malheureusement, cela doit garder ouverts deux PID et un fichier fifo
.
Variante avec un nommé fifo
Si vous ne vous embêtez pas à utiliser un nommé fifo
, vous pouvez le faire comme suit:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
Ne pas utiliser de boucle sur la lecture est un peu bâclé, mais vous pouvez le réutiliser fifo
aussi souvent que vous le souhaitez et faire le read
s terminat en utilisant touch "$HOME/.pause.fifo"
(s'il y a plus d'une lecture en attente, tout est terminé en même temps).
Ou utilisez Linux pause()
syscall
Pour le blocage infini, il y a un appel du noyau Linux, appelé pause()
, qui fait ce que nous voulons: Attendre indéfiniment (jusqu'à ce qu'un signal arrive). Cependant, il n'y a pas (encore) de programme d'espace utilisateur pour cela.
C
Créer un tel programme est facile. Voici un extrait de code pour créer un tout petit programme Linux appelé pause
qui s'interrompt indéfiniment (besoins 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 vous ne voulez pas compiler quelque chose vous-même, mais que vous l'avez python
installé, vous pouvez l'utiliser sous Linux:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Remarque: Utilisez exec python -c ...
pour remplacer le shell actuel, cela libère un PID. La solution peut être améliorée avec une redirection d'E / S également, en libérant les FD inutilisées. C'est à vous de décider.)
Comment cela fonctionne (je pense): ctypes.CDLL(None)
charge la bibliothèque C standard et exécute la pause()
fonction qu'elle contient dans une boucle supplémentaire. Moins efficace que la version C, mais fonctionne.
Ma recommandation pour vous:
Restez au sommeil en boucle. Il est facile à comprendre, très portable et bloque la plupart du temps.