it-swarm.com.de

Wie erhalte ich die PID des Hintergrundprozesses?

Ich starte einen Hintergrundprozess von meinem Shell-Skript aus und möchte diesen Prozess abbrechen, wenn mein Skript beendet ist.

Wie erhalte ich die PID dieses Prozesses aus meinem Shell-Skript? Soweit ich sehen kann, enthält die Variable $! Die PID des aktuellen Skripts, nicht den Hintergrundprozess.

339

Sie müssen die PID des Hintergrundprozesses beim Start speichern:

foo &
FOO_PID=$!
# do other stuff
kill $FOO_PID

Sie können die Auftragssteuerung nicht verwenden, da dies eine interaktive Funktion ist, die an ein steuerndes Terminal gebunden ist. Da an ein Skript nicht unbedingt ein Terminal angehängt sein muss, ist die Auftragssteuerung nicht unbedingt verfügbar.

511
camh

Du kannst den ... benutzen jobs -l Befehl, um zu einem bestimmten Job zu gelangen

^Z
[1]+  Stopped                 guard

my_mac:workspace r$ jobs -l
[1]+ 46841 Suspended: 18           guard

In diesem Fall ist 46841 die PID.

Von help jobs:

-l Zeigt die Prozessgruppen-ID und das Arbeitsverzeichnis der Jobs an.

jobs -p ist eine weitere Option, die nur die PIDs anzeigt.

130
jldupont
  • $$ ist die PID des aktuellen Skripts
  • $! ist die PID des letzten Hintergrundprozesses

Hier ist ein Beispielprotokoll einer Bash-Sitzung (%1 bezieht sich auf die Ordnungszahl des Hintergrundprozesses aus jobs):

$ echo $$
3748

$ sleep 100 &
[1] 192

$ echo $!
192

$ kill %1

[1]+  Terminated              sleep 100
45
catwalk

Eine noch einfachere Möglichkeit, alle untergeordneten Prozesse eines Bash-Skripts zu beenden:

pkill -P $$

Das -P flag funktioniert genauso mit pkill und pgrep - es werden untergeordnete Prozesse abgerufen, nur mit pkill werden die untergeordneten Prozesse beendet und mit pgrep untergeordneten PIDs werden nach Standard gedruckt.

25
Alexey Polonsky

das habe ich getan Probieren Sie es aus, ich hoffe, es kann helfen.

#!/bin/bash
#
# So something to show.
echo "UNO" >  UNO.txt
echo "DOS" >  DOS.txt
#
# Initialize Pid List
dPidLst=""
#
# Generate background processes
tail -f UNO.txt&
dPidLst="$dPidLst $!"
tail -f DOS.txt&
dPidLst="$dPidLst $!"
#
# Report process IDs
echo PID=$$
echo dPidLst=$dPidLst
#
# Show process on current Shell
ps -f
#
# Start killing background processes from list
for dPid in $dPidLst
do
        echo killing $dPid. Process is still there.
        ps | grep $dPid
        kill $dPid
        ps | grep $dPid
        echo Just ran "'"ps"'" command, $dPid must not show again.
done

Dann starte es einfach als: ./bgkill.sh mit den richtigen Berechtigungen natürlich

[email protected] [P]:~# ./bgkill.sh
PID=23757
dPidLst= 23758 23759
UNO
DOS
UID        PID  PPID  C STIME TTY          TIME CMD
root      3937  3935  0 11:07 pts/5    00:00:00 -bash
root     23757  3937  0 11:55 pts/5    00:00:00 /bin/bash ./bgkill.sh
root     23758 23757  0 11:55 pts/5    00:00:00 tail -f UNO.txt
root     23759 23757  0 11:55 pts/5    00:00:00 tail -f DOS.txt
root     23760 23757  0 11:55 pts/5    00:00:00 ps -f
killing 23758. Process is still there.
23758 pts/5    00:00:00 tail
./bgkill.sh: line 24: 23758 Terminated              tail -f UNO.txt
Just ran 'ps' command, 23758 must not show again.
killing 23759. Process is still there.
23759 pts/5    00:00:00 tail
./bgkill.sh: line 24: 23759 Terminated              tail -f DOS.txt
Just ran 'ps' command, 23759 must not show again.
[email protected] [P]:~# ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
root      3937  3935  0 11:07 pts/5    00:00:00 -bash
root     24200  3937  0 11:56 pts/5    00:00:00 ps -f
3
Luis Ramirez

Möglicherweise können Sie auch pstree verwenden:

pstree -p user

Dies gibt normalerweise eine Textdarstellung aller Prozesse für den "Benutzer" und die Option -p gibt die Prozess-ID an. Soweit ich weiß, kommt es nicht darauf an, dass die Prozesse der aktuellen Shell gehören. Es zeigt auch Gabeln.

2
villaa

Mit pgrep können Sie alle untergeordneten PIDs eines übergeordneten Prozesses abrufen. Wie bereits erwähnt $$ ist die aktuelle PID des Skripts. Wenn Sie also ein Skript wünschen, das nach sich selbst aufräumt, sollte dies der Trick sein:

trap 'kill $( pgrep -P $$ | tr "\n" " " )' SIGINT SIGTERM EXIT
1
errant.info