tail
blockiert nicht
Wie immer: Für alles gibt es eine Antwort, die kurz, leicht verständlich, leicht zu befolgen und völlig falsch ist. Hier tail -f /dev/null
fällt in diese Kategorie;)
Wenn Sie es mit betrachten, werden strace tail -f /dev/null
Sie feststellen, dass diese Lösung weit davon entfernt ist, zu blockieren! Es ist wahrscheinlich noch schlimmer als die sleep
Lösung in der Frage, da es (unter Linux) wertvolle Ressourcen wie das inotify
System verwendet. Auch andere Prozesse, die schreiben, /dev/null
um tail
Schleife zu machen . (Auf meinem Ubuntu64 16.10 werden auf einem bereits ausgelasteten System mehrere 10 Syscalls pro Sekunde hinzugefügt.)
Die Frage war nach einem Blockierungsbefehl
Leider gibt es so etwas nicht ..
Lesen Sie: Ich kenne keine Möglichkeit, dies direkt mit der Shell zu archivieren.
Alles (gerade sleep infinity
) kann durch ein Signal unterbrochen werden. Wenn Sie also wirklich sicher sein möchten, dass es nicht ausnahmsweise zurückkehrt, muss es in einer Schleife ausgeführt werden, wie Sie es bereits für Ihre getan haben sleep
. Bitte beachten Sie, dass (unter Linux) /bin/sleep
anscheinend auf 24 Tage begrenzt ist (siehe strace sleep infinity
). Daher ist das Beste, was Sie wahrscheinlich tun können, Folgendes:
while :; do sleep 2073600; done
(Beachten Sie, dass ich glaube, dass sleep
Schleifen intern für höhere Werte als 24 Tage ausgeführt werden. Dies bedeutet jedoch: Sie blockieren nicht, sie werden sehr langsam wiederholt. Warum also nicht diese Schleife nach außen verschieben?)
.. aber Sie können mit einem unbenannten ganz nah kommen fifo
Sie können etwas erstellen, das wirklich blockiert, solange keine Signale an den Prozess gesendet werden. Folgende Verwendungen bash 4
, 2 PIDs und 1 fifo
:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
Sie können überprüfen, ob dies wirklich blockiert, strace
wenn Sie möchten:
strace -ff bash -c '..see above..'
Wie das aufgebaut war
read
blockiert, wenn keine Eingabedaten vorhanden sind (siehe einige andere Antworten). Das tty
(aka. stdin
) Ist jedoch normalerweise keine gute Quelle, da es geschlossen wird, wenn sich der Benutzer abmeldet. Es könnte auch einige Eingaben von der stehlen tty
. Nicht nett.
Um zu read
blockieren, müssen wir auf so etwas wie ein warten, fifo
das niemals etwas zurückgibt. Darin bash 4
befindet sich ein Befehl, der uns genau Folgendes liefern kann fifo
: coproc
. Wenn wir auch auf die Blockierung warten read
(was unsere ist coproc
), sind wir fertig. Leider muss dies zwei PIDs und eine offen halten fifo
.
Variante mit einem Namen fifo
Wenn Sie sich nicht die Mühe machen, einen Namen zu verwenden fifo
, können Sie dies wie folgt tun:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
Das Nicht-Verwenden einer Schleife beim Lesen ist etwas schlampig, aber Sie können dies fifo
so oft wiederverwenden, wie Sie möchten, und die read
s-Terminierung verwenden touch "$HOME/.pause.fifo"
(wenn mehr als ein einziger Lesevorgang wartet, werden alle auf einmal beendet).
Oder verwenden Sie den Linux- pause()
Systemaufruf
Für die unendliche Blockierung gibt es einen Linux-Kernel-Aufruf namens pause()
, der das tut, was wir wollen: Warten Sie für immer (bis ein Signal eintrifft). Es gibt jedoch (noch) kein Userspace-Programm dafür.
C.
Ein solches Programm zu erstellen ist einfach. Hier ist ein Ausschnitt ein sehr kleines Linux - Programm aufgerufen zu erstellen , pause
die auf unbestimmte Zeit pausiert (Bedürfnisse 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
Wenn Sie etwas nicht selbst kompilieren möchten, aber python
installiert haben, können Sie dies unter Linux verwenden:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Hinweis: exec python -c ...
Zum Ersetzen der aktuellen Shell wird eine PID freigegeben. Die Lösung kann auch durch eine E / A-Umleitung verbessert werden, wodurch nicht verwendete FDs freigegeben werden. Dies liegt bei Ihnen.)
So funktioniert das (glaube ich): ctypes.CDLL(None)
Lädt die Standard-C-Bibliothek und führt die darin enthaltene pause()
Funktion in einer zusätzlichen Schleife aus. Weniger effizient als die C-Version, funktioniert aber.
Meine Empfehlung für Sie:
Bleib im Schlaf. Es ist leicht zu verstehen, sehr portabel und blockiert die meiste Zeit.