Ich habe ein Shell-Skript zum Testen einer API geschrieben, die Dateien kopiert und ihren Fortschritt nach jeder einzelnen wiedergibt.
Zwischen jeder Kopie liegt ein Ruhezustand von zwei Sekunden. Daher möchte ich die Möglichkeit hinzufügen, eine beliebige Taste zu drücken, um das Skript anzuhalten und tiefere Tests zu ermöglichen. Drücken Sie dann eine beliebige Taste, um fortzufahren.
Wie kann ich dies in so wenigen Zeilen wie möglich hinzufügen?
shell-script
blarg
quelle
quelle
sleep 10; notify-send hello
und STRG + Z drücke,notify-send hello
um anzuhalten, werde ich ausgeführt. Wenn der zweite Befehl ausgeführt wird, warum wird der erste Prozess gestoppt? danach, wenn Typ, kannfg
ich nicht sehen, dass etwas passiert, was offensichtlich ist, da der zweite Befehl bereits ausgeführt wirdcmd; cmd; cmd;
ist wie Schreibencmd <newline> cmd <newline> ...
. Alternativ zu einem Skript , das Sie schreiben können( cmd; cmd; cmd; )
, ist es wie das Drehbuch verhalten würde, bacuse der Subshell erzeugt durch(
sleep 10
. wenn ich nach 3 Sekunden STRG + Z drücke und nach wenigen Sekunden wieder aufnehme und bemerke, dass der Schlafbefehl in weniger als 7 Sekunden gestorben ist. Das ist im Gegensatz zu dem, was Sie gesagt haben, da der Befehl nevers gestoppt wird, läuft er nur im Hintergrund.strace
densleep
Befehl und fand heraus, dass der verwendete Systemaufruf istnanosleep()
. Es scheint ein definiertes Verhalten des Systemaufrufs zu seinnanosleep
.restart_syscall()
Startet den unterbrochenen Systemaufruf mit einem Zeitargument neu, das entsprechend angepasst wird, um die bereits verstrichene Zeit zu berücksichtigen (einschließlich der Zeit, zu der der Prozess durch ein Signal gestoppt wurde). Lesen Sie diese Manpage: man7.org/linux/man-pages/man2/restart_syscall.2.htmlfg %1
oder im Hintergrund (Bspbg %1
. :) . (Wenn Jobs nur 1 Nummer ausgeben, dh nur 1 angehaltenen Prozess, wie im Beispiel des Chaos gezeigt: Nur[1]+ stopped sleep 10
können Sie das%n
Teil weglassen . Wenn mehrere Hintergrundprozesse (ausgeführt oder gestoppt) vorhanden sind, müssen Sie den gewünschten angeben mit:%n
(zB:fg %2
% 2 wieder im Vordergrund haben))Wenn Sie das Skript nur anhalten möchten, während Sie im Skript verbleiben, können Sie read anstelle von sleep verwenden.
Sie können verwenden
read -t
um eine Zeitüberschreitung für das Lesen festzulegenread -n
, um ein Zeichen zu lesen (drücken Sie einfach eine beliebige Taste), um das Skript fortzusetzenDa Sie keinen Code angegeben haben, finden Sie unten ein Beispiel für die Verwendung.
Wenn q gedrückt wird, wird
read -n1
verhindert, dass das Skript fortgesetzt wird, bis eine Taste gedrückt wird.Wenn eine Taste gedrückt wird, wird die Prüfung zurückgesetzt und das Skript wird wie gewohnt in der Schleife fortgesetzt.
Sie können auch
stty -echo
am Anfang des Abschnitts undstty echo
am Ende hinzufügen , um zu verhindern, dass die Eingabe die Bildschirmausgabe durcheinander bringtquelle
Mit können
dd
Sie zuverlässig ein einzelnes Byte aus einer Datei lesen. Mit könnenstty
Sie einemin
Anzahl von Bytes festlegen , um einen Terminal-Lesevorgang und einentime
Out in Zehntelsekunden zu qualifizieren . Kombinieren Sie diese beiden und Sie könnensleep
ganz darauf verzichten, denke ich, und lassen Sie einfach die Lesezeitüberschreitung des Terminals die Arbeit für Sie erledigen:Das ist eine kleine Beispielschleife
while
, die ich verspottet habe, damit Sie sie ausprobieren können. Alle zwei Sekunden tritt einedd
Zeitüberschreitung beim versuchten Lesen vonstdin
- umgeleitet von/dev/tty
- und diewhile
Schleifenschleifen auf. Das oderdd
nicht Time-out , weil Sie eine Taste drücken - in diesem Fall eine interaktive Shell aufgerufen wird.Hier ist ein Testlauf - die am Kopf jeder Zeile aufgedruckten Zahlen sind der Wert der Shell-Variablen
$SECONDS
:quelle
stty sane
nach dem Ändern der Stty-Einstellung nicht verwenden, kann ich mich irren, aber es sieht nicht so aus, als würden Sie sie irgendwo zurücksetzen?s=$(stty -g </dev/tty)
. Unmittelbar nach dem Anrufdd
stelle ich es dann mit wieder herstty "$s"
. Der Terminalstatus kümmert sich nicht um Subshells, daher bleiben diese Einstellungen unabhängig von der übergeordneten Shell erhalten.stty sane
ist nicht unbedingt das, was Sie tun möchten - es ist besser, den Zustand so wiederherzustellen, wie Sie ihn gefunden haben, als anzunehmen, dass sich der Zustandsane
zu diesem Zeitpunkt befand. Wenn ich es nicht restaurierenecho
würde, wären diese überall. Das herauszufinden ist teilweise der Grund, warum ich so spät gekommen bin - Ihre Antwort war nicht hier, als ich anfing zu testen.