Háttérben futtatás (fg, bg, jobs, &, nohup)
Tegyük fel, hogy felhasználók vagyunk egy rendszeren, ahol nincs screen
utasítás, nincs a telepítésére jogosultságunk. Hosszan tartó dolgokat akarunk futtatni, amit nincs időnk kivárni és nem hagyhatjuk ott a gépet bejelentkezve egy másik rendszerbe, esetleg félünk hogy meg szakad a távoli kapcsolat és kezdhetjük a munkát előröl.
Utólag a háttérben (fg, bg, jobs)
Ebben az esetben a processz indítása után jövünk rá, hogy ezt inkább háttérben szeretnénk futtatni. Próba képpen indítsunk egy dd
-t ami random adatokkal tölt fel egy 1GB-os image.img fájlt.
# dd if=/dev/urandom of=image.img bs=1k count=1000000
Láthatjuk, hogy ameddig a processz nem végez, addig nem kapjuk vissza a vezérlést. De ne várjuk ki a végét, hanem nyomjuk le a CTRL+Z
billentyűt. Ez ideiglenesen megállítja a processzt. Ezek után a bg
utasítással a háttérbe küldve folytatódik a processz futása.
# dd if=/dev/urandom of=image.img bs=1k count=1000000
^Z
[1]+ Megállítva dd if=/dev/urandom of=image.img bs=1k count=1000000
# bg
[1]+ dd if=/dev/urandom of=image.img bs=1k count=1000000 &
Hogy megnézhessük a háttérben futó processzeinket, adjuk ki a jobs
utasítást.
# jobs
[1]+ Fut dd if=/dev/urandom of=image.img bs=1k count=1000000 &
Ha előtérbe akarjuk hozni a háttérbe tett processzünket, akkor erre a fg
parancsot használhatjuk.
# fg
dd if=/dev/urandom of=image.img bs=1k count=1000000
Az fg
parancs, mindig az utoljára háttérbe tett processzt hozza előtérbe. Ha több is fut háttérben és nem az utolsót akarjuk előtérbe hozni, akkor a jobs
sorszámával kiválaszthatjuk a megfelelőt.
# jobs
[1]- Fut ping google.com > /dev/null &
[2]+ Fut dd if=/dev/urandom of=image.img bs=1k count=1000000 &
# fg %1
ping google.com > /dev/null
Ugyan ez érvényes a CTRL+Z
-vel megállított processzek háttérbe tételére is.
# jobs
[1]- Megállítva ping google.com > /dev/null
[2]+ Megállítva dd if=/dev/urandom of=image.img bs=1k count=1000000
# bg %1
[1]- ping google.com > /dev/null &
# jobs
[1]- Fut ping google.com > /dev/null &
[2]+ Megállítva dd if=/dev/urandom of=image.img bs=1k count=1000000
Háttérben indítás (&, nohup)
A másik lehetőség, hogy a processzt indításakor tesszük háttérbe. Erre a sorvégi &
jelet használhatjuk.
# dd if=/dev/urandom of=image.img bs=1k count=1000000 &
[1] 13078
# jobs
[1]+ Fut dd if=/dev/urandom of=image.img bs=1k count=1000000 &
A háttérbe tett processz kezelése ugyanaz (fg
, bg
, jobs
) mint az előzőekben. Ha a háttérbe tett processznek van stdout kimenete, akkor az bizony a terminálba fog ömleni, ha csak nem irányítjuk egy fájlba vagy a /dev/null-ba ha nincs rá szükség. Ha nohup
utasítással indítunk egy processzt, akkor annak a kimenete - ha van - a nohup.out fájlba tárolódik, de ha az indítás helyére nincs írás jogunk, akkor a $HOME/nohup.out
fájlba. Persze itt is a sor végét az &
karakterrel zárjuk.
# pwd
/usr/bin
# nohup ping -c100 google.com &
[1] 13146
# nohup: bemenet figyelmen kívül hagyása és kimenet hozzáfűzése a következőhöz: ”/home/peter/nohup.out”
# jobs
[1]+ Fut nohup ping -c100 google.com &
# tail ~/nohup.out
...
64 bytes from muc03s07-in-f4.1e100.net (173.194.44.4): icmp_seq=99 ttl=55 time=32.7 ms
64 bytes from muc03s07-in-f4.1e100.net (173.194.44.4): icmp_seq=100 ttl=55 time=32.6 ms
--- google.com ping statistics ---
100 packets transmitted, 100 received, 0% packet loss, time 99068ms
rtt min/avg/max/mdev = 32.212/33.133/37.348/0.960 ms
Láthatjuk, hogy a nohup.out
fájl tartalmazza a ping
parancs kimenetét.
Ha le akarunk állítani egy háttérben futó processzt, akkor a kill
parancsal könnyedén megtehetjük. Elég csak paraméterként megadni a jobs ID-t % után.
# jobs
[1]- Fut dd if=/dev/urandom of=image.img bs=1k count=1000000 &
[2]+ Fut ping google.com > /dev/null &
# kill %1
# jobs
[1]- Befejeződött dd if=/dev/urandom of=image.img bs=1k count=1000000
[2]+ Fut ping google.com > /dev/null &
# jobs
[2]+ Fut ping google.com > /dev/null &
# kill %2
# jobs
[2]+ Befejeződött ping google.com > /dev/null
Amikor indítunk egy processzt, akkor a szülő processze általában a shell lesz, amiben indítottuk.
# pstree
...
/usr/bin/terminator
`-bash
`-dd if=/dev/urandom of=image.img bs=1k count=1000000
..
Látszik, hogy a terminator
nyitott egy shell
-t és abban indult a dd
. Háttérben futtatás nélkül a terminator vagy a shell bezárásával a dd
processz megszakad.
Ha viszont háttérben futtatjuk és úgy zárjuk be a shell-t, akkor a futása nem szakad meg, hanem a szűlője a legelső processz vagyis az init vagy systemd lesz.
Az alábbi példán látszik, hogy a dd
szülője a 17069-es processz.
# ps -ef
...
peter 17079 17069 88 20:58 pts/7 00:00:16 dd if=/dev/urandom of=image.img bs=1k count=1000000
...
Mivel háttérben futott, így a shell megszíktása után a szülő processz az 1-es lesz.
# ps -ef
...
peter 17079 1 89 20:58 ? 00:00:32 dd if=/dev/urandom of=image.img bs=1k count=1000000
...
Lám ez is milyen egyszerű :)