Jak uzyskać PID procesu w tle?

Uruchamiam proces w tle z mojego skryptu powłoki i chciałbym zabić ten proces, gdy mój skrypt się skończy.

Jak uzyskać PID tego procesu z mojego skryptu powłoki? Z tego co widzę zmienna $! zawiera PID bieżącego skryptu, a nie proces w tle.

Author: mtk, 2009-12-15

7 answers

Musisz zapisać PID procesu w tle w momencie jego uruchomienia:

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

Nie można używać kontroli zadań, ponieważ jest to funkcja interaktywna i powiązana z terminalem kontrolującym. Skrypt nie musi mieć dołączonego terminala, więc kontrola zadania nie musi być dostępna.

 441
Author: camh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-16 00:05:40

Możesz użyć polecenia jobs -l, aby dostać się do określonego jobL

^Z
[1]+  Stopped                 guard

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

W tym przypadku, 46841 jest PID.

From help jobs:

- L raportuje ID grupy procesów i katalog roboczy zadań.

jobs -p jest inną opcją, która pokazuje tylko PID.

 108
Author: jldupont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-19 15:22:35
  • $$ jest pid bieżącego skryptu
  • $! jest pid ostatniego procesu w tle

Oto przykładowy zapis z sesji bash (%1 odnosi się do liczby porządkowej procesu w tle, jak widać z jobs):

$ echo $$
3748

$ sleep 100 &
[1] 192

$ echo $!
192

$ kill %1

[1]+  Terminated              sleep 100
 38
Author: catwalk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-17 16:36:57

Jeszcze prostszy sposób na zabicie wszystkich procesów potomnych skryptu bash:

pkill -P $$

Znacznik -P działa tak samo z pkill i pgrep - pobiera procesy potomne, tylko z pkill procesy potomne są zabijane, a z pgrep PID potomne są wypisywane na stdout.

 22
Author: Alexey Polonsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-28 08:52:56

To właśnie zrobiłem. Obczaj to, mam nadzieję, że to pomoże.

#!/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

Następnie uruchom go jako: ./bgkill.sh z odpowiednimi uprawnieniami oczywiście

root@umsstd22 [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.
root@umsstd22 [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
Author: Luis Ramirez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-20 23:35:05

Możesz również użyć pstree:

pstree -p user

Zazwyczaj daje to tekstową reprezentację wszystkich procesów dla "użytkownika", a opcja-p daje identyfikator procesu. To nie zależy, o ile rozumiem, od posiadania procesów przez obecną powłokę. Pokazuje również widelce.

 2
Author: villaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-26 15:26:15

pgrep może uzyskać wszystkie pidy potomne procesu rodzica. Jak wspomniano wcześniej {[2] } to bieżący PID skryptów. Tak więc, jeśli chcesz skrypt, który sam się sprząta, to powinno załatwić sprawę: {]}

trap 'kill $( pgrep -P $$ | tr "\n" " " )' SIGINT SIGTERM EXIT
 1
Author: errant.info,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-24 04:47:48