Starten Sie die Aufgabe im Hintergrund

12

Ich weiß, dass Sie dies verwenden können, um einen Prozess im Hintergrund zu starten, ohne die Benachrichtigung zu erhalten, wenn der Prozess in den Hintergrund gestellt wird und wenn dies folgendermaßen geschieht:

(Befehl &) &> / dev / null

Dadurch wird jedoch die Option zum Abfangen entfernt, wenn der Prozess abgeschlossen ist ( trap child_done CHLD).

Wie kann ich beides haben?

Tyilo
quelle

Antworten:

5

Task-Spooler könnte Ihnen helfen.

Wie bei freshmeat.net :

Der Task-Spooler ist ein Unix-Batch-System, bei dem die gespoolten Tasks nacheinander ausgeführt werden. Die Anzahl der Jobs, die gleichzeitig ausgeführt werden sollen, kann jederzeit festgelegt werden. Jeder Benutzer in jedem System hat seine eigene Jobwarteschlange. Die Aufgaben werden im richtigen Kontext (dem der Warteschlange) von jeder Shell / jedem Prozess ausgeführt, und ihre Ausgabe / Ergebnisse können leicht überwacht werden. Dies ist sehr nützlich, wenn Sie wissen, dass Ihre Befehle von viel RAM, viel Festplattennutzung, viel Ausgabe abhängen oder aus irgendeinem Grund es besser ist, sie nicht alle gleichzeitig auszuführen, während Sie sie behalten möchten Ihre Ressourcen sind für maximalen Nutzen beschäftigt. Seine Oberfläche ermöglicht die einfache Verwendung in Skripten.

Task-Spooler ist in Debian , Ubuntu und anderen Distributionen verfügbar.

Sie können eine Reihe von Aufgaben ausführen und auf Wunsch auf deren Ausgaben zugreifen.

Beispielsweise:

$ tsp sleep 5
0 
$ tsp sleep 5 
1
$ tsp
ID   State      Output               E-Level  Times(r/u/s)   Command [run=1/1]
2    running    /tmp/ts-out.ZWn6Le                           sleep 5
1    finished   /tmp/ts-out.Fhlcle   0        5.00/0.00/0.01 sleep 5

Wenn Sie viele Jobs im Hintergrund ausführen, wird es Ihnen definitiv helfen.

Sie können sie entweder nacheinander oder in einer voreingestellten Anzahl von Slots ausführen. Sie können auch Abhängigkeiten zwischen den Tasks herstellen ( Task1 nur ausführen , wenn Task0 erfolgreich abgeschlossen wurde).

Raúl Salinas-Monteagudo
quelle
3

Hier erfahren Sie, wie Sie dies in beiden Fällen tun {ba,z}sh.

Verwendung einer Funktion hilft nicht den Zustand zu speichern und wiederherzustellen , um zsh‚s monitordurch Verwendung variabler setopt local_options.

# Run the command given by "$@" in the background
silent_background() {
  if [[ -n $ZSH_VERSION ]]; then  # zsh:  /superuser//a/1285272/365890
    setopt local_options no_notify no_monitor
    "$@" &
  elif [[ -n $BASH_VERSION ]]; then  # bash: /programming//a/27340076/5353461
    { 2>&3 "$@"& } 3>&2 2>/dev/null
  else  # Unknownness - just background it
    "$@" &
  fi
}

Verwenden Sie dies wie folgt:

trap 'echo child done' CHLD
silent_background sleep 1

Erzeugt die erwartete child doneNachricht.

Tom Hale
quelle
Eine hoffnungsvolle Erklärung finden Sie unter unix.stackexchange.com/q/456549/4778 .
Strg-Alt-Delor
2

Die Umleitung der Befehlsausgabe scheint irrelevant zu sein, da die Benachrichtigung von der Shell gesendet wird, wenn a Job asynchron gestartet wird. Genauer gesagt handelt es sich um eine Shell-Funktion (Funktion), die sich auf die Jobsteuerung bezieht .

Hier ein Zitat aus dem "Bash Reference Manual", Kapitel "Job Control", Abschnitt eins.

Die Shell ordnet jeder Pipeline einen Job zu. Es enthält eine Tabelle der aktuell ausgeführten Jobs, die mit dem jobsBefehl aufgelistet werden können . Wenn Bash einen Job asynchron startet, wird eine Zeile gedruckt, die wie folgt aussieht:

[1] 25647

Dies zeigt an, dass dieser Job Jobnummer 1 ist und dass die Prozess-ID des letzten Prozesses in der Pipeline, der diesem Job zugeordnet ist, 25647 lautet. Alle Prozesse in einer einzelnen Pipeline sind Mitglieder desselben Jobs. Bash verwendet die JOB-Abstraktion als Grundlage für die Jobsteuerung.

Beachten Sie, dass ein Shell-Skript diese Benachrichtigung nicht anzeigt.

$ cat test
#!/bin/bash

true & echo true
$ ./test
true

Eigentlich

Zsh

Die Zsh-Dokumentation enthält ähnliche Hinweise zu diesen Benachrichtigungen, siehe man 1 zshmiscAbschnitt "JOBS". Diese Benachrichtigungen werden nicht angezeigt, wenn die Jobsteuerung deaktiviert ist.

MONITOR ( -m , ksh: -m )

    Jobsteuerung zulassen. Standardmäßig in der interaktiven Shell festgelegt.

zsh_prompt % setopt no_monitor
zsh_prompt % true & echo true
true
zsh_prompt %
zsh_prompt % 

Bash

Es scheint, dass Bash immer zB anzeigt [1] 25647. Die "Endbenachrichtigung" wird zB [1]+ Done truenicht angezeigt, wenn die Jobsteuerung deaktiviert ist.

bash_prompt $ true & echo true
[1] 25647
true
bash_prompt $ 
[1]+  Done                    true

Jobsteuerung deaktiviert

bash_prompt $ set +m       # disable job control
bash_prompt $ true & echo true
[1] 25685
bash_prompt $
bash_prompt $

Fazit

Ich weiß nicht, ob es gut ist, die Jobsteuerung zu deaktivieren , um die Benachrichtigungen auszublenden.

Ressourcen

Fólkvangr
quelle
1

Sie können zshals nicht interaktive Shell aufrufen , um Jobbenachrichtigungen zu deaktivieren.

zsh -c '
   trap "echo trapped child_done" CHLD
   sleep 5 &
   #wait
   sleep 10 # simulate other running cmds
   echo script done
'
nad
quelle
0

Siehe folgendes Beispiel:

trap 'echo "DONE"' 0
{ find /usr & } &> /dev/null
wait

Das funktioniert gut. Keine Notwendigkeit ( ): Das macht eine nicht benötigte Unterschale. { }sind nur Gruppierungsbefehle.

Gilles Quenot
quelle
Das druckt [2] 49591und [2] + 49591 exit 1 find /usrwenn es keines von diesen drucken soll!
Tyilo
Entschuldigung, habe deine Frage so falsch verstanden.
Gilles Quenot
0

Dies ist eine alte Frage, aber eine mögliche Antwort (in Bash, nicht mit zsh getestet) ist die Verwendung der Jobsteuerung in der Subshell: (command & wait)

Hinweis: bash unterdrückt die Start- / End-Hintergrundjobnachrichten in der Subshell, und es ist keine Umleitung erforderlich.

Philippe
quelle
Ich denke, Sie haben den Teil mit der Falle verpasst. Soweit ich die Frage verstehe, sollte der Unterprozess gestartet werden, wird etwas getan, während der Supprozess ausgeführt wird, und wenn der Unterprozess beendet ist, sollte etwas anderes ausgeführt werden. Mit Ihrer Lösung starten Sie den Unterprozess, warten in der Unterschale darauf und die Hauptschale wartet auf die Unterschale. Dadurch werden die Nachrichten entfernt, aber Sie können nicht parallel etwas tun.
Raphael Ahrens
Nein, (sleep 5 & wait)verzögert 5 Sekunden.
Tom Hale