Wie kann ein Bash-Skript erkennen, ob es im Hintergrund ausgeführt wird?

28

Kann ein Bash-Skript erkennen, ob es im Vordergrund oder im Hintergrund ausgeführt wird und sich daher in jedem Fall geringfügig anders verhalten kann?

Dan
quelle
Beachten Sie, dass ein Prozess aufgrund der Auftragssteuerung vom Vordergrund in den Hintergrund und umgekehrt verschoben werden kann.
Barmar
1
Vielleicht interessiert Sie auch, ob das Skript in einer interaktiven Shell ausgeführt wird
GnP

Antworten:

30

Zitat man ps:

PROCESS STATE CODES

   Here are the different values that the s, stat and state output
   specifiers (header "STAT" or "S") will display to describe the state of
   a process.
   ...
   +    is in the foreground process group

Sie könnten also eine einfache Überprüfung durchführen:

case $(ps -o stat= -p $$) in
  *+*) echo "Running in foreground" ;;
  *) echo "Running in background" ;;
esac
devnull
quelle
Sicherlich läuft alles, was in $ (...) aufgerufen wird, selbst im Hintergrund ....? Ich denke, die Prozessgruppe ist das Wichtigste, kann aber nicht leugnen, dass es funktioniert.
Ed Randall
2

Schauen Sie sich die Datei "/etc/bash.bashrc" an.

Die Zeile mit "$ PS1". Dann machen Sie einen "Man Bash" und suchen Sie nach dem Token PS1.

[ -z "$PS1" ] && return

Beendet ein Skript, das nicht interaktiv ist.

user62612
quelle
1

Alle vorherigen Lösungen beinhalten Laichprozesse usw. Sehr, sehr hässlich, da .bashrcsie jedes Mal aufgerufen werden, wenn eine Bash-Shell gestartet wird. Daher beenden diese Lösungen das Starten von Tausenden von Prozessen.

Viel sauberer fragt bash selbst: bash hat eine vordefinierte Variable $-, die "i" hat, wenn sie in einer interaktiven Shell ausgeführt wird. Zum Beispiel ist es viel sauberer und billiger, dies in Ihren .bashrc zu schreiben, und am wichtigsten ist, dass es immer funktioniert!

case "$-" in 

    *i*) # interactive shell

    ;;
esac
user265919
quelle
WARUM SCHREIST DU? Das sieht sehr, sehr hässlich aus ...
Pierre.Vriens
Einfache und korrekte Lösung.
Ed Randall
0

Während Sie denken könnten, dass das Überprüfen, ob die Shell im interaktiven Modus ausgeführt wird, dasselbe Ergebnis liefert, ist dies in der Praxis nicht der Fall. Das Konzept sieht ähnlich aus, ist aber tatsächlich anders. Sie könnten dank Ihrer Erwartungen ein interaktives Skript in der Hintergrund- Feeding-Eingabe ausführen . Sie können Ihr Skript auch mit dem -lArgument bash starten . Wir können uns daher nicht auf die Bash-Interaktivität verlassen, um zu überprüfen, ob unser Skript im Hintergrund oder im Vordergrund ausgeführt wird.

Die Antwort von devnull ist also richtig . Um festzustellen, ob der Prozess im Vordergrund ausgeführt wird, überprüft das Dienstprogramm ps , ob die Prozessgruppe (pgrp) mit der Prozessgruppen-ID übereinstimmt, die dem steuernden Terminal der Sitzung (tpgid) zugeordnet ist, und fügt +der Ausgabe ein dem Prozess entsprechendes Vorzeichen hinzu Zustand.

Wenn wir das wissen, können wir definitiv eine reine Bash-Version des Tests haben:

#!/usr/bin/env bash

IFS=$' '
retval=($(</proc/$$/stat))
IFS=$' \t\n'
if [[ "${retval[3]}" == "${retval[7]}" ]]; then
    echo "Background" > ./result.txt
else
    echo "Foreground" > ./result.txt
fi
exit

Im obigen Code wird das Ergebnis in einer Textdatei ausgegeben, da stdoutkeine Verbindung besteht, wenn ein Prozess im Hintergrund ausgeführt wird.

Bitte beachten Sie, dass das vierte und das achte Element der Tabelle mit pgrpund übereinstimmen tpgid( siehe Abschnitt / proc / [pid] / stat auf der Manpage - man 5 proc).

wget
quelle