wait (Unix)
A wait a Unix shell beépített parancsa. Arra szolgál, hogy megvárja a shellből háttérben indított program(ok) kilépését, és visszaadja a programok visszatérési értékét. Alakja:
wait [ -n ] [ id... ]
id akár processz-, akár jobazonosító lehet. A jobs -l
beépített utasítás mindkét azonosítót kilistázza.
A processzazonosítót az indított program a kerneltől kapja. Ha a háttérben több programot indítottunk egyszerre (például csővezetékkel összekapcsolva), mindegyik külön processz-számot kap. A processzekről az azonosítón felüli információkat a ps paranccsal lehet lekérdezni.
A jobazonosító egy %
-jel utáni szám, melyet a shell ad minden háttér-indításkor. Ha több programot indítottunk egyszerre, a shell processzcsoportnak tekinti, és egyben kezeli őket.
A -n
kapcsolónak akkor van jelentősége, ha job id-ket adtunk meg. A wait
parancs akkor tér vissza, amikor a felsorolt programok/processzcsoportok bármelyike lefutott, és az első státusával tér vissza. Ha az -n
-et nem adtuk meg, akkor mindegyik felsorolt programot/processzcsoportot megvárja, és az utoljára befejeződött visszatérési értékét adja vissza.
Ha nem adunk meg id-t, a shell az összes háttérben indított programot/processzcsoportot megvárja, és 0-t ad visszatérési értékként.
Program indítása háttérben
Egy programot úgy indíthatunk háttérben, hogy az utasítás és paraméterek után &
-jelet írunk. A jel egyúttal utasításhatároló is, így a sorban akár több háttérben indítandó utasítás is lehet.
Ha egy programot indítottunk, a háttérben indított processz azonosítóját a $!
shell-változó tartalmazza.
Ha azt akarjuk, hogy a háttérben indított program több utasításból álljon, három lehetőségünk van. Az egyik:
prog1 ; prog2 &
A másik: kerek zárójelbe tesszük az indítandó utasítások sorozatát:
( prog1 prog2 )
Ez esetben a háttérben indított programok újabb programokat indíthatnak háttérben (a zárójelek egymásba skatulyázhatók). A zárójelbeli utasítások külön shellben hajtódnak végre.
A harmadik lehetőség: az utasításokat külön scriptbe írjuk. (A zárójel ugyanígy működik, csak nincs külön scriptneve.)
Példa
A script: sleep 5 &
( sleep 2 ; false ) &
MASODIK=$!
sleep 8 &
sleep 3 &
jobs -l
wait $MASODIK
echo A masodik processz visszateresi erteke: $?
jobs -l
sleep 3 &
echo Megvarjuk, amig az osszes hatterprocessz veget er
wait
jobs -l
|
A kimenet:[4] + 6626 Running [3] - 6625 Running [2] 6624 Running [1] 6623 Running A masodik processz visszateresi erteke: 1 [4] + 6626 Running [3] - 6625 Running [2] 6624 Done(1) [1] 6623 Running Megvarjuk, amig az osszes hatterprocessz veget er [2] + 6628 Done [4] + 6626 Done [3] + 6625 Done [1] + 6623 Done |
A kimenet első sorában [4]
a job száma (%4
-gyel lehet rá hivatkozni). A + a default job a bg és fg utasítás számára (lásd bash, job controll fejezet); %+
-szal is lehet rá hivatkozni. (A második sorban a - a default processz kilépése után kijelölt default processz, %-
-szal is lehet rá hivatkozni.) Ezt követi a processz-szám és a job állapota, Done
esetén a visszatérési értékkel, ha azt lekérdeztük.[1]
Jobon kívüli futtatás háttérben
Az indított program szülője az &
-et feldolgozó shell lesz. A program örökli a shell exportált változóit és nyitott fájljait, beleértve stdin-t, stdout-ot és stderr-t. Amikor a shell kilép, HUP (1-es) szignált küld az általa indított programoknak, melyek ettől általában ugyancsak kilépnek (bár megtehetik, hogy másképp kezelik le a HUP szignált).[2]
A nohup
parancs úgy indítja el a paraméterként kapott programot, hogy az hagyja figyelmen kívül a HUP szignált:
nohup prog param... &
Ezzel elkerülhető, hogy kijelentkezéskor leálljanak a háttérben indított programok.[3] Ha a programnak van a shell stdout-jára vagy stderr-jére írt kimenete, az az indítás könyvtárában a nohup.out
nevű fájlba kerül.
A már jobként indított háttérprogramok utólag is kivehetők a shell job-táblájából, bár ez esetben az stdin, stdout, stderr és a többi nyitott fájl marad az indításkori.[4] A paraméter nélkül kiadott disown
utasítás megváltoztatja az utoljára a háttérben indított program szülőjét. Ettől a háttérprogram függetlenedik az indító shelltől, így annak kilépése sem befolyásolja a futását.
A disown
utasítás -h
kapcsolójával utólag elérhető, hogy a háttérprocessz ne fogadjon HUP szignált. Ilyenkor a szülője marad az indító shell, így a jobs
utasítás mutatni fogja, de a shell kilépése után is tovább fut.
A gyakorlatban a disown
helyett általában a nohup
parancsot használják.
Jegyzetek
- ↑ Please explain the output from the jobs command (StackExchange)
- ↑ A shell parancssorból is tud szignált küldeni: lásd kill parancs.
- ↑ Természetesen nem kötelező a
nohup
-ot háttérben indítani, bár a parancsot erre találták ki. - ↑ Mire a
disown
utasításra sor kerül, a program már írhatott az örökölt nyitott fájlokba.
Források
- BASH: launch background process and check when it ends (StackExchange)
- shell - get exit code of background process (stackoverflow)
További információk
- Running bash commands in the background properly (Felix Milea-Cinobanu)