I avsnitt 3.2 beskrev vi det gränssnitt till jobbkontroll som Bash erbjuder. I detta avsnitt ska vi ta upp fler sätt att kontrollera och manipulera processer.
Med hjälp av kommandot ps kan man kontrollera
vilka processer som är igång på datorn.$ ps
PID TTY STAT TIME COMMAND
5596 p0 S 0:00 -bash
5599 p2 S 0:01 /usr/bin/xdvi.bin -name xdvi gnulinux.dvi
5639 p2 S 0:00 gs -sDEVICE=x11 -dNOPAUSE -dSAFER -q -
5668 p0 R 0:00 ps
$ Status för en process (rubriken STAT ovan) kan vara
R (Running; igång),
S (Sleeping; sysslolös) och
T (Stopped; stoppad, eller snarare pausad).
Instruktionen som startade respektive process anges
i sista fältet av varje rad ovan. Det näst sista fältet
visar hur mycket av datorns tid instruktionen tagit i
anspråk.
Varje process har ett nummer, dess processidentifikationsnummer (PID), med vars hjälp man referar till processen. De flesta processer har en kontrollterminal, nämligen den terminal processen startades från. Eventuell indata till kommandot läses in från kontrollterminalen, och utdata skrivs ut där. Det andra fältet (under rubriken TTY) ovan anger processens kontrollterminal.
Varje terminal motsvaras av en fil i katalogen /dev. De virtuella terminalerna, som man kommer till genom samtidigt att trycka Ctrl, Alt och en av funktionstangenterna F1 till F6, har filnamn tty1 till tty6, medan pseudoterminaler har filnamn ttyp1, ttyp2 osv. Kommandot ps från sista raden ovan körs i pseudoterminalen /dev/ttyp0.
Flaggorna till ps anges på ett något
annorlunda sätt än vanligt
(detta kommer att ändras i en kommande utgåva av programmet).
Om man ger flaggan u, så skrivs utförligare
information ut.$ ps u
USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND
göran 5596 0.0 1.9 1832 1228 p0 S 08:32 0:00 -bash
göran 5599 0.0 3.4 3160 2184 p2 S 08:33 0:01 /usr/bin/xdvi.bi
göran 5639 0.0 3.9 4540 2528 p2 S 10:07 0:00 gs -sDEVICE=x11
göran 5670 0.0 0.8 908 540 p0 R 10:39 0:00 ps u
$ Här ser vi också vem som startade processen (USER),
när den startades (START),
hur många procent av datorns tid (%CPU)
respektive minne (%MEM) processen förbrukar,
hur stor processen är (SIZE, i kilobyte) samt
hur mycket av den som finns i minnet just nu
(RSS).
Bara de processer man själv startat listas ovan.
Använd flaggan a om också alla andras
processer ska tas med.
De processer som inte har någon kontrollterminal
finns inte heller med ovan, utan man måste ge ps
flaggan x
för att få information om dem.$ ps x
PID TTY STAT TIME COMMAND
5580 ? S 0:01 /usr/X11R6/bin/fvwm2
5592 ? S 0:00 /usr/X11R6/lib/X11/fvwm2/FvwmPager 9
5594 ? S 0:00 /usr/X11R6/lib/X11/fvwm2/FvwmButtons
5595 ? S 0:00 xclock -update 1 -padding 4 -bg Dark
5596 p0 S 0:00 -bash
5598 ? S 0:58 /usr/bin/xemacs
5599 p2 S 0:01 /usr/bin/xdvi.bin -name xdvi gnulinu
5639 p2 S 0:00 gs -sDEVICE=x11 -dNOPAUSE -dSAFER -q
5672 p0 R 0:00 ps x
$ De processer som saknar kontrollterminal har ett frågetecken
under rubriken TTY. I utskriften ovan finns fem sådana
processer; de utgörs av fönsterhanteraren och program
som startats genom den.
Kommandot top ger ungefär samma information som ps. Men top sorterar processerna efter hur mycket processortid de använder, och informationen uppdateras med jämna intervall tills man trycker q. Man skulle kunna säga att top är en ''live-version'' av ps. Det finns åtskilliga X-program som ger motsvarande information, tex Gtop, se figur 5.1.
Här är ett exempel på utdata från programmet top:
10:53am up 16 days, 22:07, 3 users, load average: 0.00, 0.00, 0.10
41 processes: 40 sleeping, 1 running, 0 zombie, 0 stopped
CPU states: 3.7% user, 0.9% system, 0.0% nice, 95.4% idle
Mem: 63356K av, 61184K used, 2172K free, 26664K shrd, 9376K buff
Swap: 96352K av, 316K used, 96036K free 23856K cached
PID USER PRI NI SIZE RSS SHARE STAT LIB %CPU %MEM TIME COMMAND
5675 göran 19 0 772 772 592 R 0 3.7 1.2 0:00 top
15350 root 8 0 5268 5260 1596 S 0 0.9 8.3 61:42 XF86_Mach64
1 root 0 0 232 216 160 S 0 0.0 0.3 0:01 init
2 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 kflushd
3 root -12 -12 0 0 0 SW< 0 0.0 0.0 0:00 kswapd
4 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsiod
5 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsiod
6 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsiod
7 root 0 0 0 0 0 SW 0 0.0 0.0 0:00 nfsiod
15326 root 0 0 972 972 656 S 0 0.0 1.5 0:00 bash
15324 root 0 0 312 312 232 S 0 0.0 0.4 0:00 getty
119 root 0 0 580 548 452 S 0 0.0 0.8 0:05 sshd
14 root 0 0 92 64 52 S 0 0.0 0.1 0:07 update
85 root 0 0 372 364 272 S 0 0.0 0.5 0:00 syslogd
87 root 0 0 360 352 180 S 0 0.0 0.5 0:00 klogd
96 root 0 0 204 196 148 S 0 0.0 0.3 0:00 kerneld
100 daemon 0 0 344 340 268 S 0 0.0 0.5 0:00 portmap
102 root 0 0 376 368 300 S 0 0.0 0.5 0:00 inetd
152 root 0 0 304 284 224 S 0 0.0 0.4 0:00 getty
126 root 0 0 760 748 356 S 0 0.0 1.1 22:00 rpc.nfsd
128 root 0 0 568 556 444 S 0 0.0 0.8 0:00 rpc.mountd
132 nobody 0 0 272 264 204 S 0 0.0 0.4 0:00 dhttpd
135 daemon 0 0 308 276 220 S 0 0.0 0.4 0:00 atd
138 root 0 0 348 340 256 S 0 0.0 0.5 0:00 cron
30196 root 0 0 1544 1544 1204 S 0 0.0 2.4 0:00 xdm
153 root 0 0 296 296 216 S 0 0.0 0.4 0:00 getty
15348 root 0 0 684 672 572 S 0 0.0 1.0 0:00 xdm
5580 göran 1 0 1284 1284 896 S 0 0.0 2.0 0:01 fvwm2
5590 root 0 0 2104 2104 1448 S 0 0.0 3.3 0:01 xterm
30205 root 0 0 1436 1436 1196 S 0 0.0 2.2 0:00 xconsole.real
5592 göran 0 0 720 720 620 S 0 0.0 1.1 0:00 FvwmPager
5595 göran 0 0 1260 1260 1052 S 0 0.0 1.9 0:00 xclock
5594 göran 0 0 808 808 696 S 0 0.0 1.2 0:00 FvwmButtons
5596 göran 15 0 1228 1228 884 S 0 0.0 1.9 0:00 bash
30150 root 0 0 1456 1436 700 S 0 0.0 2.2 2:29 sshd
5599 göran 0 0 2184 2184 1328 S 0 0.0 3.4 0:01 xdvi.bin.real
5598 göran 0 0 7464 7464 3056 S 0 0.0 11.7 1:01 xemacs
5639 göran 0 0 2528 2528 1736 S 0 0.0 3.9 0:00 gs
30152 eva 0 0 1176 1176 860 S 0 0.0 1.8 0:00 bash
30154 eva 0 0 9544 9540 1876 S 0 0.0 15.0 0:48 gimp
30155 eva 0 0 1996 1980 708 S 0 0.0 3.1 0:00 script-fu
Man kan ''kommunicera'' med en process genom att skicka signaler till den med hjälp av kommandot kill. Ofta används kill till att avsluta processer, men kommandot kan också ha andra, mindre destruktiva effekter - tex att processen tar en paus eller att den startar om. Bara root och ägaren av en process får skicka signaler till den.
Signaler har såväl namn som nummer. Man kan referera till en signal antingen med dess namn, som tex SIGCONT (eller kortare CONT), eller dess nummer, som 18. Några viktiga signaler ges i tabell 5.2.
Processer kan förbereda sig för att ta emot olika signaler, och ha en åtgärd redo ifall en viss signal skulle komma. Man säger då att processen fångar signalen. Åtgärden kan vara att helt enkelt strunta i signalen, eller tex att spara alla data, skriva ett felmeddelande och avsluta. Om signalen inte fångas, så vidtas en standardåtgärd på processen. Två av signalerna, SIGKILL och SIGSTOP, kan aldrig fångas.
Vi minns att man kan pausa ett förgrundsjobb
i Bash genom att trycka C-z.
Mer allmänt kan man pausa en process
genom att skicka signalen
SIGSTOP till den.
För att låta processen fortsätta kan man
vid ett senare tillfälle skicka signalen
SIGCONT till den.$ gzip -9 /tmp/gnulinux.ps &
[1] 5682
$ ps 5682
PID TTY STAT TIME COMMAND
5682 p0 R 0:04 gzip -9 /tmp/gnulinux.ps
$ kill -STOP 5682
$ ps 5682
PID TTY STAT TIME COMMAND
5682 p0 T 0:14 gzip -9 /tmp/gnulinux.ps
[1]+ Stopped gzip -9 /tmp/gnulinux.ps
$ kill -CONT 5682
$ ps 5682
PID TTY STAT TIME COMMAND
5682 p0 R 0:21 gzip -9 /tmp/gnulinux.ps
$ ls /tmp
gnulinux.ps.gz
[1]+ Done gzip -9 /tmp/gnulinux.ps
$ Ovan körs först en tung process igång.
Med hjälp av ps ser vi att processen kör för fullt.
Kommandot kill -STOP 5682 skickar
signalen SIGSTOP till processen,
och en kontroll visar att den faktiskt är pausad
(dess status är T). Efter en stund skickas signalen
SIGCONT till processen, och då fortsätter den
därifrån den stannade. Dess status är återigen R.
Senare, efter kommandot ls /tmp,
ser vi att processen kört färdigt.
Kommandot kill vill som flagga
ha namn eller nummer på en signal att skicka.
Om flaggan utelämnas, så skickas signalen
SIGTERM. Argumenten består av
ett eller flera processidentifikationsnummer,
som anger vilken eller vilka processer signalen
ska skickas till.
Om kill anropas med flaggan -l,
så ges en lista över alla signaler.$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR
$
Signalen SIGTERM är en önskan om att processen ska avsluta. Vissa processer fångar denna signal och struntar i den. Andra processer fångar signalen, sparar sina data och städar upp efter sig innan de avslutar. Slutligen finns det processer som inte fångar signalen SIGTERM, och då vidtas standardåtgärden som är att avsluta dem. Om man vill ta bort en process som inte ger med sig på något annat sätt, så kan man skicka SIGKILL till den. Då avslutas processen utan att den först ''tillfrågas''. Detta kan ha obehagliga effekter - om man tex skickar SIGKILL till Emacs, så förlorar man alla ändringar som inte är sparade. Det är alltså bäst att prova SIGTERM först; bara om detta inte hjälper ska man använda SIGKILL.
Antag att vi har följande processer igång:$ ps
PID TTY STAT TIME COMMAND
1485 p1 S 0:00 -bash
1491 p2 S 0:00 -bash
1502 p3 S 0:00 xdvi.bin -name xdvi oh.dvi
1549 p2 R 54:05 dedekind 1232112423
1598 p1 R 0:00 ps
$Vi försöker nu ta bort process 1491, ett Bash-skal:$ kill 1491
$ ps 1491
PID TTY STAT TIME COMMAND
1491 p2 S 0:00 -bash
$Kontrollen med ps visar att Bash-skalet finns kvar.
Detta beror på att Bash fångar signalen SIGTERM
och struntar i den. Vi måste då ta till SIGKILL:$ kill -9 1491
$ ps 1491
PID TTY STAT TIME COMMAND
No processes available.
$Utskriften från ps visar att processen är borttagen.
Process 1549 (som körde under det skal vi nyss tog bort
och som nu saknar kontrollterminal)
kan vi däremot ta bort med SIGTERM:$ ps 1549
PID TTY STAT TIME COMMAND
1549 ? R 62:33 dedekind 1232112423
$ kill 1549
$ ps 1549
PID TTY STAT TIME COMMAND
No processes available.
$
När man i skalet trycker C-c skickas signalen SIGINT till de processer som är i förgrunden. Detta får vanligtvis processerna att avsluta.
Signalen SIGHUP betyder att processen
är ''avringd'', vilket tex kan innebära
att man loggat ut. Vissa processer struntar i
denna signal, andra avlutar och åter andra
läser in sina konfigurationsfiler och startar om.
Om man vill att en process ska ligga kvar även efter
att man loggat ut, så måste man i vissa fall skydda
den mot signalen SIGHUP. Detta gör man genom
att starta den med nohup kommando &
Om ett program ''utför en förbjuden åtgärd'', så skickas signalen SIGSEGV till den. Nästan alltid får detta till följd att programmet avslutar och gör en minnesutskrift i en fil med namnet core. Minnesutskriften är till för att programutvecklare ska kunna ta reda på vad som vållade felet.
Kommandot killall är en variant av kill.
Skillnaden mellan dessa kommandon
ligger i hur man anger vilka processer signalen ska
skickas till.
I fallet kill anges processernas PID,
men till killall anges i stället
det kommando som startade processerna.
En fördel med killall är att vi slipper ta reda
på PID för processerna ifråga.$ xfontsel &
[1] 5874
$ killall xfontsel
[1]+ Avslutad xfontsel
$
Om en process startar en ny process, så är den nya processen
barn till den gamla, och den gamla processen är
förälder till den nya.
Förälderns PID kallas för processens PPID.
Kommandot pstree ritar ut processernas
släktträd med utgångspunkt från urmodern init
(som har PID 1)
eller, om man vill, från en given process.$ ps x
PID TTY STAT TIME COMMAND
5580 ? S 0:04 /usr/X11R6/bin/fvwm2
5592 ? S 0:00 /usr/X11R6/lib/X11/fvwm2/FvwmPager 9
5594 ? S 0:00 /usr/X11R6/lib/X11/fvwm2/FvwmButtons
5596 p0 S 0:00 -bash
5598 ? S 1:48 /usr/bin/xemacs
5599 p2 S 0:02 /usr/bin/xdvi.bin -name xdvi gnulinu
5639 p2 S 0:00 gs -sDEVICE=x11 -dNOPAUSE -dSAFER -q
5868 ? S 0:00 xclock -update 1 -padding 4 -bg Dark
5876 p0 R 0:00 ps x
$ pstree 5580
fvwm2-+-FvwmButtons
|-FvwmPager
|-xclock
`-xterm---bash---pstree
$
Varje process har ett snällhetsvärde som bestämmer hur stor del av processorns tid processen får. Värdet är ett heltal mellan -20 och 19. Ju högre värdet är, desto snällare är processen i den meningen att den kräver mindre av processorkraften. Vanligtvis ärver en process snällhetsvärdet från sin förälder; standardvärdet är 0. Det är bara root som får sänka snällhetsvärdet för en process. Däremot kan vanliga användare höja det för sina processer med kommandot nice. Om en process startas med nice kommando, så ges den ett snällhetsvärde som är 10 enheter större än dess förälder (men högst 19). Om den ska ha tex värdet 5 högre än föräldern, ska den startas med instruktionen nice -n 5 kommando. Om man ger denna instruktion i ett skal med snällhetsvärde 10, så körs alltså kommando med snällhetsvärde 15. Snällhetsvärdet skrivs ut under rubriken ''NI'' i top, se tabell 5.1.
Om en process redan är igång, så kan man ändra dess
snällhetsvärde med kommandot renice.
Nedan startar vi en process och sätter sedan dess snällhetsvärde
till 3.$ xfontsel &
[1] 5935
$ renice +3 5935
5935: old priority 0, new priority 3
$Vi ändrar snällhetsvärdet till 7:$ renice +7 5935
5935: old priority 3, new priority 7
$Man får inte sänka värdet, utan bara höja det.$ renice +5 5935
renice: 5935: setpriority: Åtkomst nekas
$