PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bash: Wie forken?



Linus
07-09-2007, 20:19
Ich brauche in einem Skript einen Child-Prozess und die PID davon.

Nimmt man dafür am Besten

bash <command> &

und wie bekommt man die PID davon heraus? :confused:

jan61
07-09-2007, 20:57
Jeder Aufruf eines (nicht bash-builtin-) Programms aus einer Shell (es sei denn, per exec gestartet) macht einen fork. Es reicht also einfach der Kommandoaufruf.

Die PID kriegst Du z. B. über pidof oder ps raus. Eine nette Variante ist auch, bei einem in den Hintergrund geschickten Prozess (also Kommando &) sich die PID mittels des Bash-Builtins jobs -l zu holen.

Jan

BLUESCREEN3D
08-09-2007, 14:44
und wie bekommt man die PID davon heraus?
Nach "command &" einfach die Variable $! auslesen:

sleep 1m &
echo $!

Linus
08-09-2007, 15:12
Nach "command &" einfach die Variable $! auslesen:

sleep 1m &
echo $!

Aha, funktioniert das auch mit Funktionen? :confused:

jan61
08-09-2007, 19:21
Moin,

@BLUESCREEN3D: Den Parameter $! hatte ich ganz vergessen - man wird alt ;-)


Aha, funktioniert das auch mit Funktionen? :confused:

Ja, scheint so zu sein, wobei das aus dem bash-Manual nicht so deutlich hervorgeht:

...Functions are executed in the context of the current shell;
no new process is created to interpret them (contrast this with the
execution of a shell script)...Wenn ich eine Funktion in den Hintergrund schicke, dann allerdings wird offenbar eine Subshell gestartet und deren PID kann ebenfalls mit $! abgefragt werden.

Was unterschiedlich zu externen, im Hintergrund gestarteten Programmen ist: Innerhalb der Funktion ist $$ immer noch die PID der startenden Shell und der laufende Prozess kann nicht mit der Job-Kontrolle der Bash gelistet oder gesteuert werden.

Ich habe das mal mit einem kleinen Testprogramm ausprobiert:

jan@jack:~/tmp> nl bash_child.sh
1 function my_sleep() {
2 x=0
3 while test $x -lt 100; do
4 x=`expr $x + 1`
5 sleep 2
6 done
7 }

8 tty
9 echo MAIN $$
10 ps -p $$ -o cmd,args
11 my_sleep &
12 echo HINTERGRUND $!
13 ps -p $! -o cmd,args
Ruft man jetzt das Script auf, dann erscheint folgende Ausgabe:
jan@jack:~/tmp> bash bash_child.sh
/dev/pts/2
MAIN 22588
CMD COMMAND
bash bash_child. bash bash_child.sh
HINTERGRUND 22591
CMD COMMAND
bash bash_child. bash bash_child.sh
Nimmt man in Zeile 11 das & weg und sieht sich die Prozessausgabe in einem anderen Fenster an, dann sieht das Ganze so aus:
jan@jack:~> ps -ef | grep pts/2
jan 7386 7050 0 18:30 pts/2 00:00:00 /bin/bash
jan 22951 7386 0 19:17 pts/2 00:00:00 bash bash_child.sh
jan 22959 22951 0 19:17 pts/2 00:00:00 sleep 2
Hier läuft also tatsächlich nur ein Prozess.

Jan

Linus
08-09-2007, 22:54
Aha, danke :)