Bash: unendlicher Schlaf (unendliche Blockierung)
Benutze ich startx
start von X die Bewertung meiner .xinitrc
. In meinem .xinitrc
ich mein window-manager mit /usr/bin/mywm
. Nun, wenn ich töte meine WM (um f.e. testen Sie einige andere WM), X wird beendet, weil die .xinitrc
Skript erreicht EOF.
Also ich habe dies am Ende meiner .xinitrc
:
while true; do sleep 10000; done
Diesem Weg X nicht kündigen, wenn ich töte meine WM. Nun meine Frage: wie kann ich einen unendlichen Schlaf statt looping schlafen? Gibt es einen Befehl, die sich ein bisschen wie freeze das Skript?
Beste Grüße
InformationsquelleAutor der Frage watain | 2010-05-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
sleep infinity
macht genau das, was es vermuten lässt und funktioniert, ohne Katze Missbrauch.InformationsquelleAutor der Antwort Donarsson
Vielleicht dies scheint hässlich, aber warum nicht einfach laufen
cat
und lassen Sie es warten für die Eingabe forever?InformationsquelleAutor der Antwort Michał Trybus
tail
nicht blockiertWie immer: Für alles gibt es eine Antwort, die kurz, leicht zu verstehen, leicht zu Folgen und völlig falsch. Hier
tail -f /dev/null
fällt in diese Kategorie 😉Wenn man es mit
strace tail -f /dev/null
Sie werden feststellen, dass diese Lösung ist weit von der Sperrung! Es ist wahrscheinlich noch schlimmer als diesleep
Lösung in der Frage, wie es verwendet (unter Linux), wertvolle Ressourcen wie dieinotify
system. Auch andere Prozesse, die schreiben/dev/null
machentail
Schleife. (Auf meinem Ubuntu64 16.10 dies fügt mehrere 10 Aufrufe pro Sekunde auf einer bereits ausgelasteten system.)Die Frage war eine Sperrung Befehl
Leider gibt es keine solche Sache ..
Lesen: ich kenne keinen Weg, um dieses Archiv mit der shell direkt.
Alles (auch
sleep infinity
) kann unterbrochen werden, indem einige signal. Also, wenn Sie wollen wirklich sicher, dass es nicht außergewöhnlich Rückkehr, muss es in einer Schleife ausführen, wie Sie schon für Ihresleep
. Bitte beachten Sie, dass (auf Linux)/bin/sleep
anscheinend ist begrenzt auf 24 Tage (haben Sie einen Blick aufstrace sleep infinity
), so dass die beste Sie tun können, ist wahrscheinlich:(Beachten Sie, dass ich glaube, dass
sleep
Schleifen intern für höhere Werte als 24 Tage, aber das bedeutet: Es ist nicht blockiert, es ist sehr langsam Schleifen. Also warum nicht gehen Sie diese Schleife auf der Außenseite?).. aber Sie kommen ganz nahe an eine Unbenannte
fifo
Können Sie etwas schaffen, das wirklich blockiert, solange es keine Signale senden, um den Prozess. Folgende Verwendungen
bash 4
2 PIDs und 1fifo
:Können Sie überprüfen, dass dies wirklich Blöcke mit
strace
wenn Sie mögen:Wie diese gebaut wurde,
read
blockiert, falls keine Eingabe-Daten (siehe einige andere Antworten). Jedoch, dietty
(aka.stdin
) ist normalerweise keine gute Quelle, da es geschlossen ist, wenn sich der Benutzer abmeldet. Auch könnte es stehlen einige, input aus dertty
. Nicht schön.Machen
read
block, wir müssen warten, bis so etwas wie einfifo
die nie etwas zurückzugeben. Inbash 4
gibt es einen Befehl, die können genau bieten, uns mit solchenfifo
:coproc
. Wenn wir warten auch auf die Sperrungread
(was ist unsercoproc
), wir sind fertig. Leider muss dies offen zu halten, zwei PIDs und einefifo
.Variante mit einem Namen
fifo
Wenn Sie nicht die Mühe mit einer benannten
fifo
Sie können dies tun, wie folgt:Nicht mit einer Schleife, auf der zu Lesen ist ein bisschen schlampig, aber Sie können wiederverwendet werden diese
fifo
so oft wie Sie möchten und machen Sie dieread
s terminat mittouch "$HOME/.pause.fifo"
(wenn es mehr als einen single-read wartet, alle sind terminiert auf einmal).Oder verwenden Sie den Linux -
pause()
syscallFür die infinite Sperrung gibt es eine Linux-kernel-Aufruf, genannt
pause()
die tut, was wir wollen: ewig Warten (bis ein signal kommt). Allerdings gibt es keine userspace-Programm für diese (noch) nicht.C
Erstellen Sie ein solches Programm ist einfach. Hier ist ein snippet, um eine sehr kleine Linux-Programm namens
pause
die Pausen auf unbestimmte Zeit (mussdiet
gcc
etc.):python
Wenn Sie nicht wollen, zu kompilieren, selbst etwas, aber Sie haben
python
installiert haben, können Sie diese unter Linux:(Hinweis: Verwenden Sie
exec python -c ...
zum ersetzen der aktuellen shell, das schafft eine PID. Die Lösung verbessert werden kann, mit einigen IO-Umleitung, als auch, zu befreien, ungenutzte FDs. Dies ist bis zu Ihnen.)Wie das funktioniert (glaube ich):
ctypes.CDLL(None)
lädt die standard-C-Bibliothek und führt diepause()
Funktion innerhalb einige zusätzliche Schleife. Weniger effizient ist als die C-version, aber funktioniert.Meine Empfehlung für Sie:
Aufenthalt im looping schlafen. Es ist leicht zu verstehen, sehr tragbar, und blockiert die meisten der Zeit.
InformationsquelleAutor der Antwort Tino
TL;DR:
sleep infinity
tatsächlich schläft die maximal zulässige Zeit, die endlich ist.Sich Fragen, warum diese nicht dokumentiert überall, ich die Mühe gemacht, zu Lesen Quellen aus den GNU coreutils und ich fand es ausführt, etwa wie folgt:
seconds
variable.xnanosleep(seconds)
(gefunden in gnulib), diese wiederum ruftdtotimespec(Sekunden)
(auch in gnulib) konvertieren vondouble
zustruct timespec
.struct timespec
ist nur ein paar von ganzen zahlen: integer-Teil (in Sekunden) und der gebrochene Teil (in Nanosekunden).Naiv konvertieren positive infinity zu Ganzzahl erzeugen würde Undefiniertes Verhalten (siehe §6.3.1.4 vom C-standard), so anstatt es schneiden zu
TYPE_MAXIMUM (time_t)
.TYPE_MAXIMUM (time_t)
ist nicht in der standard - (auchsizeof(time_t)
ist das nicht); also, für den sake des Beispiels nehmen wir x86-64-aus einer aktuellen linux-kernel.Dies ist
TIME_T_MAX
im Linux-kernel, die definiert ist (time.h
):Beachten Sie, dass
time_t
ist__kernel_time_t
undtime_t
istlong
; die LP64-Datenmodell verwendet wird, sosizeof(long)
8 (64 bit).Welche ergibt:
TIME_T_MAX = 9223372036854775807
.Ist:
sleep infinite
Ergebnisse in eine tatsächliche Schlafzeit von 9223372036854775807 Sekunden (10^11 Jahre). Und für 32-bit-linux-Systeme (sizeof(long)
4 (32 bits)): 2147483647 Sekunden (68 Jahre; siehe auch das Jahr 2038 problem).Bearbeiten: offenbar ist die
nanoseconds
Funktion, die aufgerufen wird, die nicht direkt den Systemaufruf, sondern eine OS-abhängige wrapper (auch definiert in gnulib).Gibt es einen zusätzlichen Schritt, wie ein Ergebnis: bei einigen Systemen, wo
HAVE_BUG_BIG_NANOSLEEP
isttrue
der Schlaf ist verkürzt auf 24 Tage und dann in einer Schleife aufgerufen. Dies ist der Fall für einige (oder alle?) Linux-Distributionen. Beachten Sie, dass dieser wrapper kann nicht verwendet werden, wenn eine konfigurieren-Zeit-test ist erfolgreich (Quelle).Insbesondere, dass wäre
24 * 24 * 60 * 60 = 2073600 seconds
(plus 999999999 Nanosekunden); dies ist aber in einer Schleife aufgerufen, um die Achtung der angegebene total sleep time. Daher die bisherigen Schlussfolgerungen bleiben gültig.In der Schlussfolgerung, die daraus resultierende Zeit schlafen ist nicht unendlich, aber hoch genug für alle praktischen Zweckeauch wenn die daraus resultierenden tatsächlichen Zeitablauf nicht tragbar; das hängt vom OS und Architektur.
Antwort auf die ursprüngliche Frage, das ist offensichtlich gut genug, aber wenn aus irgendeinem Grund (ein sehr resource-constrained Systems), die Sie wirklich wollen, vermeiden Sie ein unnötiges extra countdown-timer, ich denke, die richtige alternative ist die Verwendung der
cat
Methode beschrieben in den anderen Antworten.InformationsquelleAutor der Antwort jp48
sleep infinity
sieht sehr elegant, aber manchmal ist es nicht aus irgendeinem Grund arbeiten. In diesem Fall können Sie versuchen andere blockierenden Befehle wiecat
read
tail -f /dev/null
grep a
etc.InformationsquelleAutor der Antwort Hui Zheng
Was über die Zusendung eines SIGSTOP selbst?
Diese sollten angehalten werden, den Prozess bis SIGCONT empfangen wird. Das ist in deinem Fall: nie.
InformationsquelleAutor der Antwort michuelnik
Vor kurzem hatte ich die Notwendigkeit, dies zu tun. Ich kam mit der folgenden Funktion, die es ermöglichen bash zu schlafen, für immer, ohne Aufruf von beliebigen externen Programm:
HINWEIS: ich habe bereits geschrieben, eine version, die dem öffnen und schließen des Datei-Descriptors jedes mal, aber ich fand, dass es auf einigen Systemen zu tun das mehrere hundert Male pro Sekunde würde schließlich einsperren. So ist die neue Lösung hält die den Datei-descriptor zwischen den aufrufen der Funktion. Bash wird es sauber auf die Ausfahrt sowieso.
Diese können aufgerufen werden, so wie /bin/sleep, und es wird Platz für die angefragte Zeit. Ohne Parameter aufgerufen, wird es immer hängen.
Es gibt ein Dokument verfasst mit übermäßigen details auf meinem blog hier
InformationsquelleAutor der Antwort bolt
Statt töten den Fenster-manager, versuchen, das neue mit
--replace
oder-replace
wenn verfügbar.InformationsquelleAutor der Antwort Dennis Williamson
kein warten auf Kind-Prozess.
InformationsquelleAutor der Antwort shuaiming