Sessió 5 dia 11/04
Control de tasques
Tasques programades: AT i CRON
Resum d'ordres del terminal. Gestió de processos.
El control de tasques és una utilitat inclosa en la majoria dels intèrprets d'ordres, i permeten el control del multitud de tasques o ordres alhora en un sol terminal.
Els processos poden estar en Primer Pla o en Segon Pla. En primer pla solament pot haver un procés alhora i aquest és precisament el que veiem, en altres paraules el que interactua amb nosaltres donant-nos una sortida o demanant dades, el qual rep les ordres del teclat. En canvi el procés en segon pla no rep senyal des del teclat i s'executa en silenci.
Si un programa triga molt a acabar i no mostra res interessant per pantalla el més lògic seria executar-lo en segon pla, com pogués ser la compressió d'un arxiu enorme. Si ho fem així podrem seguir usant l'ordinador per fer qualsevol altra cosa.
Un procés pot ser suspès (dormit), el que indica que temporalment estarà desocupat i més tard podríem reprendre'l per a quan ho necessitem.
O bé quan ja no ens interessi un procés podrem interrompre'l i acabar amb ell.
Veurem una ordre que per a mi és gairebé totalment inútil però que ens servirà molt bé per a les explicacions, és l'ordre:
yes [string]
Aquesta ordre simplement repetirà el que li indiquem en 'string' indefinidament, i en defecte d'això ens donarà una llista de 'y' si no li indiquem res.
Per provar-lo teclegem yes i a veure què passa:
ramon@portatil:$ yes y y y ....
Avorrits de veure 'y' sense parar el que farem és matar-lo per avorrit ;) per a això premerem 'Ctrl + c' i ja està.
Com al fer les proves no ens interessa estar mirant un munt de 'y' el que farem és redirigir la sortida de l'ordre 'yes' cap a '/dev/null' que és alguna cosa així com un forat negre, és a dir, tot el que allí enviem desapareix (més d'un voldria un '/dev/null' en la vida real).
Enviant al segon pla
Ara el que volem fer és arrencar l'ordre yes amb la redirecció a '/dev/null' i arrencar-lo en segon pla aconseguint una bonica despesa de CPU :). Per a enviar-lo a segon pla hem d'afegir el símbol '&' al final de la línia, com veiem en l'exemple.
ramon@portatil:$ yes > /dev/null & [1] 8042 ramon@portatil:$
Aquest és el resultat, tornem a tenir el prompt per a nosaltres i dos curiosos nombres. Aquests dos nombres són les referències a la tasca, el '[1]' representa el nombre de tasca i el 8042 és l'identificador de procés o PID, que és ni més ni menys el nombre que li assigna el sistema al procés.
Però on s'ha ficat?
I ara què fem per veure què ha passat amb la nostra ordre? Doncs simple, usarem una de les ordres internes de l'intèrpret d'ordres, aquesta és 'jobs' que dóna un llistat de les tasques que tenim en execució i el seu estat:
ramon@portatil:$ jobs [1]+ Running yes > /dev/null & ramon@portatil:$
Com veieu ens indica el nombre de tasca, l'estat (en aquest cas corrent o millor dit executant-se) i la forma que ho cridem.
Més formes de matar
Seguint amb les nostres ganes d'eliminar a 'yes' del nostre sistema (ara no ens val 'Ctrl + c' ) tenim 2 formes de fer-lo amb una mateixa ordre, aquesta és 'kill' que així sense més envia un senyal de fi de procés al procés que li indiquem.
Per fer-lo tenim dues formes de referenciar-la, la més còmoda seria amb el nombre de tasca i per a això usem el símbol '%' de la següent manera:
ramon@portatil:$ kill %1 ramon@portatil:$
Així que recordeu, per usar el nombre de tasca cal usar un '%' davant i per a usar el PID simplement posarem el PID. Així que 'kill %1' i 'kill 8042' serien equivalents.
I per a cerciorar-nos de la seva defunció consultem al nostre 'jobs':
ramon@portatil:$ jobs [1]+ Acabat yes > /dev/null ramon@portatil:$
Cal destacar que 'jobs' guarda la informació del procés mort per a mostrar-la 1 vegada, ja que si executem de nou 'jobs' ja res se sabrà de la tasca morta:
ramon@portatil:$ jobs ramon@portatil:$
També disposem de l'ordre killall per matar els processos. La usem seguida del nom del procés que volem matar. Vegem un exemple:
ramon@portatil:$ jobs [2]+ Stopped yes > /dev/null [3]- Running yes > /dev/null & ramon@portatil:$ killall yes ramon@portatil:$ jobs [2]+ Stopped yes > /dev/null [3]- Acabat yes > /dev/null ramon@portatil:$
Aturar i continuar
Hi ha altra forma d'enviar una tasca a segon pla i és executar-la normalment i fer-la suspendre's o dormir-se, per a això usarem la combinació de tecles 'Ctrl+z':
ramon@portatil:$ yes > /dev/null (Aquí vaig prémer Ctrl + z) [1]+ Stopped yes > /dev/null ramon@portatil:$ jobs [1]+ Stopped yes > /dev/null ramon@portatil:$
Per tornar-la a reprendre en primer pla usarem l'ordre interna 'fg' (foreground) continuant la tasca just on es va deixar (cal recalcar que quan una tasca està parada no usa temps de CPU).
ramon@portatil:$ fg yes > /dev/null [1]+ Stopped yes > /dev/null ramon@portatil:$
Veiem com l'hem reprès i l'hem tornat a parar, però en aquest cas ja sí que l'enviarem al segon pla amb l'ordre interna 'bg' (background), que continuarà amb l'execució de l'ordre en segon pla.
ramon@portatil:$ bg [1]+ yes > /dev/null & ramon@portatil:$
Recapitulant
Les tasques poden estar en primer i segon pla, i aquestes poden estar bé executant-se, desocupades o acabades (mortes). Les tasques en segon pla no poden parar-se ni eliminar-les mitjançant 'Ctrl + c' sinó que abans cal passar-les a primer pla per poder realitzar això.
Una tasca parada no consumeix temps de CPU, però segueix mantenint la memòria que estigués usant, simplement espera que se li doni l'oportunitat de continuar amb la seva tasca.
Encara que una tasca en segon pla no pot rebre res des del teclat, sí que pot enviar dades a la pantalla i pot resultar molt molest.
Per exemple, si se't hagués ocorregut executar 'yes &' no podrides detenir-lo amb 'Ctrl + c' o amb 'Ctrl + z' ja que està en segon pla, però ens està aclaparant amb una tira interminable de 'y' que no ens deixa veure el nostre prompt, amb el que per remeiar això hem de teclejar a cegues 'fg' per portar-nos la tasca al primer pla i aquesta vegada sí la podrem parar per aquest mètode (també podríem haver-la eliminat amb un 'kill' a cegues amb el seu nombre de tasca).
Més sobre 'fg' i 'bg'
Aquestes dues ordres actuen sobre l'últim procés parat o creat, indicat per un '+' quan executem 'jobs' (mireu els exemples anteriors). Si tinguéssim diverses tasques per indicar-li a 'fg' i 'bg' sobre quin actuar utilitzaríem, com amb 'kill', el símbol '%' més el seu nombre de tasca.
ramon@portatil:$ yes > /dev/null & [2] 8142 ramon@portatil:$ yes > /dev/null & [3] 8143 ramon@portatil:$ yes > /dev/null & [4] 8145 ramon@portatil:$ jobs [1] Running yes > /dev/null & [2] Running yes > /dev/null & [3]- Running yes > /dev/null & [4]+ Running yes > /dev/null & ramon@portatil:$ fg %2 yes > /dev/null (Aquí vaig prémer Ctrl + z) [2]+ Stopped yes > /dev/null ramon@portatil:$ jobs [1] Running yes > /dev/null & [2]+ Stopped yes > /dev/null [3] Running yes > /dev/null & [4]- Running yes > /dev/null & ramon@portatil:$ kill %1 ramon@portatil:$ kill %4 [1] Acabat yes > /dev/null ramon@portatil:$ ramon@portatil:$ jobs [2]+ Stopped yes > /dev/null [3] Running yes > /dev/null & [4]- Acabat yes > /dev/null ramon@portatil:$
Ordres associades
ps mostra els processos del sistema. Amb les opcions a, x i l ens mostra tots els processos d'una forma ampliada.
ramon@portatil:$ ps axl F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 5 105 7837 1 26 10 1740 740 - SNs ? 0:00 /sbin/syslo 0 1000 7938 1 16 0 33628 15272 - Sl ? 0:16 gedit 0 1000 8006 1 15 0 39212 14372 - Sl ? 0:04 gnome-termi 0 1000 8007 8006 18 0 2224 656 - S ? 0:00 gnome-pty-h 0 1000 8008 8006 16 0 4800 1836 wait Ss pts/0 0:00 bash 0 1000 8142 8008 25 0 3348 428 finish T pts/0 0:11 yes 0 1000 8143 8008 25 0 3348 428 - R pts/0 1:58 yes 0 1000 8182 8008 18 0 4148 732 - R+ pts/0 0:00 ps axl ramon@portatil:$
top llista els processos en execució de forma interactiva
ramon@portatil:$ top Tasks: 86 total, 2 running, 83 sleeping, 1 stopped, 0 zombie Cpu(s): 99.0% us, 1.0% sy, 0.0% ni, 0.0% id, 0.0% wa, 0.0% hi, 0.0% si Mem: 256300k total, 242352k used, 13948k free, 4884k buffers Swap: 522072k total, 11648k used, 510424k free, 61944k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8143 ramon 25 0 3348 428 364 R 95.1 0.2 5:51.42 yes 6244 root 15 0 56152 23m 8780 S 2.3 9.2 0:43.86 Xorg 8006 ramon 15 0 39300 14m 9464 S 2.3 5.7 0:05.24 gnome-terminal 7502 ramon 15 0 20812 9m 7868 S 0.3 4.0 0:00.72 mixerapplet2 1 root 16 0 1552 488 444 S 0.0 0.2 0:00.56 init 2 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
L'ordre nice estableix la prioritat que ha de tenir un procés que encara no està en execució. Si se li passa com paràmetre una ordre juntament amb la prioritat desitjada, ajusta la prioritat de l'ordre a l'especificada. Exemple: (el color vermel només és per resaltar l'exemple)
root@portatil:/home/ramon # nice -10 find / > /dev/null & [1] 8531 root@portatil:/home/ramon # top top - 03:00:47 up 51 min, 2 users, lloeu average: 0.73, 0.72, 0.67 Tasks: 87 total, 1 running, 86 sleeping, 0 stopped, 0 zombie Cpu(s): 0.3% us, 8.3% sy, 0.7% ni, 0.0% id, 89.7% wa, 1.0% hi, 0.0% si Mem: 256300k total, 253152k used, 3148k free, 29216k buffers Swap: 522072k total, 11648k used, 510424k free, 44212k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8531 root 26 10 3384 556 400 D 8.0 0.2 0:02.56 find 108 root 5 -10 0 0 0 S 0.3 0.0 0:00.94 kblockd/0 6244 root 15 0 56920 23m 9548 S 0.3 9.5 1:23.54 Xorg
renice canvia la prioritat d'un procés que s'està executant
root@portatil:/home/ramon # nice -10 find / > /dev/null & [1] 8565 root@portatil:/home/ramon # renice -0 8565 8565: prioritat antiga 10, nova prioritat 0 root@portatil:/home/ramon # top top - 03:03:30 up 54 min, 2 users, lloeu average: 1.05, 0.89, 0.74 Tasks: 87 total, 2 running, 85 sleeping, 0 stopped, 0 zombie Cpu(s): 4.0% us, 9.0% sy, 0.0% ni, 0.0% id, 84.7% wa, 2.3% hi, 0.0% si Mem: 256300k total, 253256k used, 3044k free, 27932k buffers Swap: 522072k total, 11648k used, 510424k free, 44076k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8565 root 18 0 3384 556 400 R 7.3 0.2 0:03.60 find 8006 ramon 16 0 39668 14m 9516 S 2.7 5.9 0:35.85 gnome-terminal
pidof ens retorna el PID d'un procés passant-li el nom del procés
root@portatil:/home/ramon # find / > /dev/null & [1] 8616 root@portatil:/home/ramon # pidof find 8616
nohup executa ordres immunes a que l'ordinador es pengi i als tancaments de sessió.
ramon@portatil:~$ nohup find / > /dev/null & [1] 8637 ramon@portatil:~$
i si a continuació féssim 'exit' el procés continuaria executant-se.
AT
at ens serveix per programar tasques que s'han d'executar abans que la màquina s'apagui.
atd és el dimoni que s'encarrega de gestionar els treballs d'at.
at gestiona treballs per a una posterior execució.
atq llista les tasques pendents.
atrm seguit del nombre de tasca esborra la tasca pendent.
Exemples:
root@portatil:/home/ramon # date mar abr 12 03:22:31 CEST 2005 root@portatil:/home/ramon # at 03:30 today warning: commands will be executed using /bin/sh at> poweroff at> <EOT> (Aquest EOT surt quan prems 'Ctrl + D') job 1 at 2005-04-12 03:30 root@portatil:/home/ramon # atq 1 2005-04-12 03:30 a root root@portatil:/home/ramon # atrm 1 root@portatil:/home/ramon # atq root@portatil:/home/ramon #
CRON
cron és el dimoni que s'encarrega de gestionar els treballs de crontab.
crontab -e edita tasques programades.
crontab -l llista les tasques programades.
crontab -r esborra tasques programades.
minuts hora dia mes mes dia setmana usuari ordre de 0 a 59 de 0 a 23 d'1 a 30/31 d'1 a 12 d'1 a 7
Exemple:
perquè cada dia la màquina es pari a les 21:00 escriuríem alguna cosa així:
0 21 * * * root poweroff
Si volem que una tasca s'executi cada 5 hores hem d'usar la barra '/' i escriure alguna cosa semblat a això:
* /5 * * * usuari tasca
Existeixen quatre carpetes on podem posar executables o enllaços a executables perquè s'executin amb la periodicitat que nosaltres vulguem (horària, diària, setmanal o mensual). Aquestes carpetes són:
/etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly
root@portatil:/home/ramon # cat /etc/crontab # /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file. # This file also has a username field, that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || run-parts --report /etc/cron.daily 47 6 * * 7 root test -x /usr/sbin/anacron || run-parts --report /etc/cron.weekly 52 6 1 * * root test -x /usr/sbin/anacron || run-parts --report /etc/cron.monthly #