Wie kann man Strg + C / Nicht / Unterbrechen der while-Schleife machen?

11

Angesichts dieser Schleife:

while sleep 10s ; do
  something-that-runs-forever
done

Wenn ich Strg + C drücke, wird die gesamte while-Schleife unterbrochen. Was ich tun möchte, ist, den "Etwas" -Prozess zu unterbrechen, 10 Sekunden verstreichen zu lassen und dann "Etwas" neu zu starten.

Wie bewege ich Strg + C nur "etwas" und nicht die while-Schleife?

EDIT: "Interrupt" wie in SIGINT. Töten. Abbrechen. Kündigen. Nicht "unterbrechen" wie in "Pause".

bos
quelle
Wenn Sie es nur anhalten möchten, können Sie Strg + Z verwenden, 10 Sekunden warten und ausführen fg. Warum überhaupt Strg + C verwenden?
Terdon
@terdon: Danke für den Kommentar, vielleicht bin ich mit der Antwort hereingestürzt.
Müssen
@terdon: Ich möchte es nicht pausieren. Ich möchte, dass 10 Sekunden vergehen, wie ich geschrieben habe.
Bos
Sie sagten : What I want to do is to interrupt the "something"-process, let 10 seconds pass, and then restart "something". Wenn Sie Strg + Z drücken, 10 Sekunden warten und dann ausführen fg, passiert genau das. Vielleicht könnten Sie Ihre Frage bearbeiten und ein bestimmtes Beispiel geben, damit wir es besser verstehen können?
Terdon
3
Ich dachte, dass im Kontext von Strg + C Interrupt eindeutig war, aber offensichtlich habe ich mich geirrt. Ich habe jetzt bearbeitet.
Bos

Antworten:

18

Es sollte funktionieren, wenn Sie nur trap SIGINTzu etwas. Like :( true).

#!/bin/sh
trap ":" INT    
while sleep 10s ; do
    something-that-runs-forever
done

Wenn Sie das something...unterbrechen, wird die Shell jetzt nicht beendet, da das Signal ignoriert wird. Wenn Sie den sleepProzess jedoch beenden, wird er mit einem Fehler beendet und die Schleife wird aufgrund dessen gestoppt. Bewegen Sie das sleepin das Innere der Schleife oder fügen Sie etwas hinzu || true, um dies zu verhindern.

Beachten Sie, dass wenn Sie trap "" INTdas Signal vollständig ignorieren (anstatt ihm einen Befehl zuzuweisen), es auch im untergeordneten Prozess ignoriert wird, sodass Sie es auch nicht unterbrechen something...können. Dies wird zumindest in Bashs Handbuch ausdrücklich erwähnt :

Wenn arg die Nullzeichenfolge ist, wird das von jeder Sigspec angegebene Signal von der Shell und den von ihr aufgerufenen Befehlen ignoriert. [...] Signale, die beim Eintritt in die Shell ignoriert werden, können nicht abgefangen oder zurückgesetzt werden.

ilkkachu
quelle
Kann dies auch in der aktuellen Shell erreicht werden? (Nicht in einem Skript.)
1
Möglicherweise möchten Sie do (trap - INT; something-that-runs-forever)eine Unterbrechung des Befehls zulassen. Außerdem müssen Sie nicht ausgeführt werden. :Sie können einfach eine leere Zeichenfolge verwenden, um ein Signal zu ignorieren : trap '' INT. All dies ist POSIX und sollte auf jeder kompatiblen Shell (nicht nur auf Bash) funktionieren.
Toby Speight
Beachten Sie auch, dass das SIGINTvollständige Schreiben nicht unbedingt portierbar ist: " Implementierungen können Namen mit dem SIGPräfix zulassen oder Groß- und Kleinschreibung in Signalnamen als Erweiterung ignorieren . " (Meine Betonung)
Toby Speight
Sie können die leere Zeichenfolge als Aktion übergeben, um ein Signal zu ignorieren, z. B. trap "" INT(auch Posix)
daf
@TobySpeight, der Grund , warum ich verwendet , trap :anstatt trap ""war genau das, um nicht das Signal ignoriert zu haben (aber es ist ein no-op stattdessen machen), so dass wir nicht brauchen , etwas anderes zu tun zu können , die wichtigsten zu unterbrechen somethingProgramm.
Ilkkachu
0

Eine andere Möglichkeit besteht darin, something-that-runs-foreverdas Signal zu verarbeiten (bei Empfang ordnungsgemäß zu beenden). Natürlich ist es nur sinnvoll, wenn dieses Programm in vielen Skripten verwendet wird und das gewünschte Verhalten auf CTRL+ Csystematisch dasselbe ist - um die Skriptausführung fortzusetzen.

Dmitry Grigoryev
quelle
ITYM "schlafen und sich selbst neu ausführen", nicht "anmutig beenden"?
Toby Speight