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?
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?
Antworten:
Zitat man ps
:
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
Alle vorherigen Lösungen beinhalten Laichprozesse usw. Sehr, sehr hässlich, da .bashrc
sie 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
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 -l
Argument 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 stdout
keine Verbindung besteht, wenn ein Prozess im Hintergrund ausgeführt wird.
Bitte beachten Sie, dass das vierte und das achte Element der Tabelle mit pgrp
und übereinstimmen tpgid
( siehe Abschnitt / proc / [pid] / stat auf der Manpage - man 5 proc
).