Wie führe ich einen Befehl verzögert im Hintergrund aus?

33

Kann mir jemand zeigen, wie man ein Programm erstellt, um diese Aktion durchzuführen: nach 5 Minuten

echo "80" > /sys/class/leds/blue/brightness

Ich möchte, dass dieses Programm im Hintergrund läuft (wie der rngdDienst). Ich kann das nicht, weil ich nicht so viel über Linux weiß.

user53337
quelle

Antworten:

51
( sleep 300 ; echo "80" > /sys/class/leds/blue/brightness ) &

Auf diese Weise wird Ihr Skript fortgesetzt oder Sie stellen die Kontrolle sofort wieder her, während eine neue Hintergrundaufgabe des Skripts mit zwei Befehlen gestartet wird: sleep und echo.

Der gemeinsame Fehler versucht , entweder zu geben sleepoder echooder beide &, das nicht wie vorgesehen. Wenn Sie eine Reihe von Befehlen ()starten, werden diese in einem separaten Shell-Prozess erzeugt, mit dem Sie die gesamten Befehle in den Hintergrund verschieben können &.


Insofern, als ich es als nützlich empfand. In einem eingebetteten Gerät, das ich entwickle, gibt es die Hauptanwendung, die mit einem Watchdog arbeitet. Wenn dies so fehlschlägt, dass der Watchdog-Reset kurz nach dem Start wiederholt ausgelöst wird, kann dies nur schwer aus der Ferne behoben werden, da die Zeitspanne zwischen dem Start des Betriebssystems und dem Zurücksetzen recht kurz ist und nicht ausreicht, um den App-Start zu blockieren. Ich brauche also eine Möglichkeit, um festzustellen, ob das System so schnell neu gestartet wurde, und gegebenenfalls eine Verzögerung einzuführen, damit ich Zeit habe, sie manuell zu beheben.

 [ -f /tmp/startdelay ] && sleep 30
 touch /tmp/startdelay
 ( sleep 30 ; rm /tmp/startdelay ) &
 [ -f /tmp/noautostart ] && exit 0
 start_app

Wenn ich mich anmelde und touch /tmp/noautostartdie Haupt-App durchführe, wird sie nicht gestartet. Wenn der Watchdog startet, rm /tmp/startdelaynicht ausgeführt wird und das nächste Mal das System startet, habe ich zusätzliche 30 Sekunden Zeit, um ihn zu stoppen. Andernfalls erfolgt der Neustart unverzüglich.

SF.
quelle
Ja, ich stimme zu, aber das kann auch Teil der Benutzerreflexion sein
;-)
Andere Antworten scheinen den Teil "im Hintergrund" zu verpassen. Nein, ich war ziemlich explizit darüber: /
Goldlöckchen
@goldilocks: Du hast den Teil zum Senden in den Hintergrund erst hinzugefügt, nachdem ich meine Antwort gepostet habe.
SF.
Nein, meine ursprüngliche Antwort war, eine Funktion mit sleep auszuführen, um den Schlaf &zu untermalen. "Sie müssen auch den Schlaf im Hintergrund" stand von Anfang an in der ersten Zeile. Wenn Sie mir nicht glauben, schauen Sie sich den Bearbeitungsverlauf an. Und meine Antwort ist 5 Minuten älter als deine: P
Goldlöckchen
1
@gekannt: ... ähm, die Frage ist "Wie wird ein Befehl verzögert im Hintergrund ausgeführt ?" - wie würden Sie es sonst erreichen? (Und nein, wenn Sie die ()Gruppe nicht im Hintergrund haben , wird die ursprüngliche Shell angehalten, bis die erzeugte beendet ist.)
SF.
11

benutze den atBefehl

echo "echo \"80\" > /sys/class/leds/blue/brightness" | at now + 5 min

das läuft im hintergrund

exussum
quelle
2
Dies ist der richtige Weg, aber es muss der atd-Daemon laufen und auf den meisten Systemen muss ein Paket installiert sein.
Julian
Sie können einfache Anführungszeichen verwenden, um das Entkommen zu vermeiden, und echoganz darauf verzichten, indem Sie einen Heredoc oder Herestring verwenden.
Chris Down
@Julian atist ein POSIX-Standardbefehl. Auf welchem ​​Unix-ähnlichen System ist es standardmäßig nicht verfügbar?
Stéphane Chazelas
1
@ StéphaneChazelas - gute Frage. Ich weiß, dass ich dieses Problem hatte, aber es ist eine Weile her. Ich habe ein wenig nachgesehen und das Kommando scheint ziemlich allgegenwärtig zu sein. Es scheint auch, dass atd Linux-spezifisch ist und sogar auf einigen Linux-Systemen durch einen Cron-Daemon im BSD-Stil ersetzt werden kann. Lassen Sie uns meinen Kommentar als veraltet betrachten.
Julian
Ich habe 'at' ausprobiert und auf Android 8 wurde kein Befehl gefunden
beppe9000
6

Wenn Sie möchten, dass in 5 Minuten etwas ausgeführt wird, der Rest Ihres Programms jedoch fortgesetzt (oder beendet) wird, müssen Sie auch den Ruhezustand im Hintergrund anzeigen:

#!/bin/bash

runWithDelay () {
    sleep $1;
    shift;
    "${@}";
}

runWithDelay 3 echo world &
echo hello    

Dies wird gedruckt hellound dann 3 Sekunden später (nachdem das Hauptprogramm beendet wurde) gedruckt world.

Der wichtige Teil ist &, die Funktionsausführung in den Hintergrund zu rücken.

Goldlöckchen
quelle
1
Darf ich runWithDelay () { sleep $1; "${@:2}"; }stattdessen vorschlagen ?
manatwork
1
Ich denke, es sollte doWhateverWithDelay 3 &in Ihrem zweiten Beispiel gelesen werden .
Baarn
@manatwork: Prost.
Goldlöckchen
1
@goldilocks, das Wesentliche bei der Verwendung $@ist, dass Sie es zitieren können und als Liste der zitierten Wörter erweitert werden. Also mach es besser "$@"(oder "${@}"wenn du die Zahnspange magst). Siehe pastebin.com/MU7hbB2C
Manatwork
@manatwork: Point taken;) Ich habe das mit args with echo ( -n) versucht, aber das war natürlich ein bisschen naiv.
Goldlöckchen