Processen programmeren voor automatische uitvoering

Maak gebruik van de daluren

Een multi-user systeem zoals Linux kan heel wat te lijden hebben, maar de ergste momenten zijn gewoonlijk gedurende de kantooruren. En of een systeem nu bij je thuis staat of op kantoor, 's ochtends, 's avonds, 's nachts en in het weekend gebeurt er meestal niet veel. Deze idle time gebruiken en zo de belasting spreiden in de tijd kan veel goedkoper zijn dan de aanschaf van nieuwe, snellere machines, die je zou nodig hebben als je alles tegelijk wilt doen.

Er zijn drie manieren uitgestelde taken in te plannen:

  • Een korte tijd wachten en daarna de taak uitvoeren, gebruik makend van het sleep commando. Het tijdstip van uitvoering hangt af van het tijdstip waarop de taak gepland werd.

  • De taak uitvoeren op een welbepaald tijdstip met het at commando. Het tijdstip van uitvoering is niet afhankelijk van het tijdstip van planning.

  • Een taak steeds opnieuw uitvoeren, maandelijks, wekelijks, dagelijks, elk uur of elke minuut, door gebruik te maken van de cron faciliteit.

We zullen elk van de mogelijkheden nu bespreken.

Het sleep commando

Wat doet sleep?

De man of info pagina van sleep is waarschijnlijk een van de kortste documentaties over programma's ooit. Het enige dat sleep doet, is wachten. Standaard wordt de wachttijd uitgedrukt in seconden. Hoewel programmeurs de sleep funktie beter kennen dan gewone gebruikers, kunnen we het programma toch nuttig toepassen, ook als gewone gebruiker.

Voorbeeld: lunchtijd

Iemand belt je op om te vragen of je mee komt lunchen, en je zegt “OK, ik ben er over een half uurtje”, maar je verdrinkt zowat in het werk en zal bijna zeker de afspraak vergeten. Gebruik het volgende commando in zo'n geval:

[Belangrijk]Doe mee

Onderstaand voorbeeld kan je zelf makkelijk testen.

willy@ubuntu:~$ (sleep 1800; echo -e "\a Etenstijd..") &

Exact een half uur later (1800 seconden) zal je een belsignaal horen en een tekst in je terminal venster zien verschijnen.

Deze combinatie van commando's verdient wel wat verdere uitleg:

  • Twee commando's worden na elkaar uitgevoerd: sleep en echo. Ze worden van elkaar gescheiden door een puntkomma.

  • De twee commando's worden gezamenlijk in de achtergrond geplaatst door ze tussen ronde haken te zetten, die gevolgd worden door een ampersand.

  • Eerst wordt het sleep commando uitgevoerd, als dat voltooid is volgt echo, waarmee je tekst op het scherm kan zetten. We zagen het gebruik van echo reeds eerder om de inhoud van variabelen te tonen.

  • Met de -e bij echo geef je aan dat speciale karakters geïnterpreteerd moeten worden, zoals bijvoorbeeld “\a”, wat staat voor een belkarakter. Zie de man pagina van echo voor meer informatie.

  • Het is een goede gewoonte om strings (series van karakters) tussen aanhalingstekens te zetten, zodat ze allemaal tesamen beschouwd worden. Doe je dat niet, dan beschouwt het systeem elke string na een spatie als een nieuwe string. Als je ooit shell programma's gaat schrijven, moet je dit weten.

Het echo commando kan natuurlijk ook vervangen worden door een ander commando, bijvoorbeeld een zware taak die je moet uitvoeren wanneer de andere gebruikers naar huis zijn, maar je moet zelf ook je trein halen en wilt niet wachten tot iedereen weg is, en het is al 20 voor 5:

willy@ubuntu:~$ (sleep 5000; zwaar_programma) &

Daarna kan je uitloggen of je scherm vergrendelen.

Voorbeeld: grote printjobs

Stel je voor: je hebt net op het werk een drietal boeken van het Internet geplukt en je wilt ze afdrukken om ze thuis rustig te kunnen lezen. Maar als je alles in één keer afdrukt, zullen je collega's gedurende een uur of langer niets kunnen afdrukken, omdat jouw bestanden zo groot zijn. Gebruik het volgende commando om je collega's tussen elk boek 20 minuten de kans te geven om een briefje van enkele bladzijden af te drukken:

willy@ubuntu:~$ lp boek_1; sleep 1200; lp boek_2; sleep
1200; lp boek_3

Het lp commando wordt gebruikt om via het terminal venster bestanden af te drukken. Printers instellen en bestanden afdrukken wordt verder besproken in de paragraaf “Geluid afspelen”.

[Opmerking]Sleep voor programmeurs

Programmeurs kennen de sleep funktie zeer goed, bijvoorbeeld opdat een programma een bepaalde tijd op input van de gebruiker zou wachten alvorens verder te gaan.

Het at commando

Wat doet at?

Het at commando voert andere commando's uit op een gegeven tijdstip. De opties bij at zijn tamelijk gebruiksvriendelijk. Geef het at commando in, gevolgd door het tijdstip waarop de geplande taak uitgevoerd moet worden. Daarmee kom je in de at omgeving, gekenmerkt door de at prompt. Hier geef je het commando of de commando's in die gepland moeten worden. Als je gedaan hebt, typ je Ctrl+D en de taak wordt gepland.

Voorbeeld: compileren

Hieronder een voorbeeld van het maken van een programma, het zou bijvoorbeeld een experimentele versie van firefox kunnen zijn. Op UNIX en Linux gebeurt het wel vaker dat je een programma zelf vanaf de broncode moet maken of compileren, zoals dat heet. Daarvoor heb je twee commando's nodig: het eerste is configure, een programma dat meegeleverd wordt met de broncode, dat je systeem analyzeert en bepaalt op welke manier de software voor jouw computer gebouwd moet worden. Het tweede commando is make, dat je normaalgezien op elk UNIX_achtig systeem vindt. Het maken van software kan wel eens zware belastingen tot gevolg hebben. Daarom kan je die taak beter 's avonds of 's nachts uitvoeren, zodat niemand er last van heeft (incluis jijzelf). Wat vooraf ging: je hebt in zo'n gevallen de broncode van het Internet of een ander medium afgehaald, je hebt ze uitgepakt en dan kan je beginnen. Het maken van de software wordt om half drie 's nachts gedaan in dit voorbeeld:

willy@ubuntu:~$ at 2:30
warning: commands will be executed using /bin/sh
at> cd /var/tmp/firefox_experiment
at> ./configure
at> make
at> <EOT>
job 1 at 2006-06-24 02:30
willy@ubuntu:~$ 
[Belangrijk]Weet je nog?

Waarom zou hier het commando ./configure gebruikt worden, en niet gewoon configure?

Op het moment dat je Ctrl+D drukt, komt de melding “<EOT>”, wat staat voor End OF Transmission. Je krijgt nog eens te zien wanneer de taak uitgevoerd zal worden.

[Opmerking]Fictie

Bovenstaand voorbeeld is een fictieve opdracht. In het echte leven kan je gelijkaardige opdrachten laten uitvoeren, maar de bestandsnamen zullen zeker verschillen. In elk geval vereist het beschikking over broncode van een programma.

De commando's atq en atrm

Je kan een overzicht krijgen van alle at jobs met het commando atq:

willy@ubuntu:~$ atq
1	2006-06-23 02:30 a willy

Indien je je bedenkt, bijvoorbeeld omdat er bij nader inzien een fout in je commando's geslopen is, gebruik dan het atrm commando om de job te verwijderen. Gebruik het jobnummer uit de eerste kolom van de output van atq als argument:

willy@ubuntu:~$ atrm 1
willy@ubuntu:~$ atq
willy@ubuntu:~$ 

Controleer altijd met atq of je opdracht gelukt is.

Lees de man pagina's van at, atq en atrm.

[Belangrijk]Testbestanden aanmaken

Kijk hoe laat het nu is. Voer een at commando in dat over een half uur uitgevoerd wordt en dat in de map /var/tmp een testmap aanmaakt, met daarin drie testbestanden.

Het cron systeem

Wat is cron?

De cron daemon draait constant op je systeem. Deze dienst gaat elke minuut na of er taken uit te voeren zijn voor de gebruikers of voor de diensten die op een systeem draaien. De taken worden opgeslagen in zogenaamde crontabs (tabellen). Elke gebruiker kan een crontab hebben, waarin elke lijn een taak voorstelt die regelmatig herhaald moet worden. Verder is er ook nog een crontab waarin de systeem-specifieke taken vernoemd worden, zoals bijvoorbeeld:

  • Dagelijks de index maken waarvan het locate commando gebruik maakt;

  • Dagelijks nagaan of er updates zijn voor de software op het systeem;

  • Er dagelijks voor zorgen dat logbestanden, waarin informatie wordt opgeslagen over wat er allemaal op het systeem gebeurd is, niet te groot worden.

  • Dagelijks en wekelijks een index maken van alle man pagina's, zodat apropos en whatis kunnen werken.

Andere taken kunnen zijn: het maken van backups, rapporten opmaken en doorsturen, systeeminformatie analyzeren en doormailen naar de administrator, herinneringsbrieven mailen, enzovoorts. Alle taken die periodiek uitgevoerd moeten worden, komen voor opname in het cron systeem in aanmerking.

De crontabs voor het systeem vind je in de /etc map, die van de gebruikers in /var/spool/cron/crontabs, maar die map is niet toegankelijk voor de niet-gepriviligieerde gebruiker. In /var/spool/cron vind je ook nog atjobs en atspool, omdat de at jobs onder de verantwoordelijkheid van de cron daemon vallen.

Cron gebruiken

Om een crontab te kunnen maken, moeten we een editor kunnen gebruiken. Voorlopig zullen we de standaard teksteditor gebruiken, nano. Het is belangrijk om een tekst editor te gebruiken, en niet zomaar eender welke word processor. Die laatste gaat namelijk allerlei formateringsinformatie stockeren in het bestand dat je wilt schrijven, en daar kan ons systeem niet mee om. We moeten het bestanden geven waarin elk karakter leesbaar is en waarin elk karakter ingelezen kan worden zoals het zich voordoet, toch op zijn minst wanneer het configuratiebestanden betreft. Je kan je dit voorstellen als zou je met Notepad op MS Windows een Office document proberen te openen (.doc): Notepad ziet ook alle formateringsinformatie en kan er niet mee om, zodat je allerlei rare karakters op je scherm krijgt en haast niets van de eigenlijke tekst kan lezen.

Dus willen we een editor die geen extra informatie opslaat, een “WYSIWYG” of “What You See Is What You Get” editor. We zullen later zien dat nano niet de enige mogelijkheid is, en zeker niet de standaard op alle Linux systemen.

De crontab editeren

Om je persoonlijke crontab te editeren, geef je het commando crontab -e in. Met de -e zal er een slot op het bestand in /var/spool/cron/crontabs/jouw_gebruikersnaam gezet worden, zodat je niet twee keer hetzelfde bestand kan editeren. Mocht dat slot er niet zijn, dan zou je je crontab kunnen beginnen schrijven, afgeleid worden en in een tweede terminal venster een nieuwe crontab openen, waarmee je de veranderingen van de eerste zou kunnen overschrijven.

Na het ingeven van dat commando krijg je een relatief leeg scherm, de nano editor heeft een nieuw, tijdelijk bestand voor je geopend.

Deze editor werkt zeer gemakkelijk, de mogelijke akties staan onderaan beschreven. Bijvoorbeeld om een bestand af te sluiten, staat er dat je “^X” moet ingeven. Het circumflex accent staat voor een combinatie met de Ctrl toets, je moet dus Ctrl+X ingeven om een bestand weg te schrijven.

Bij wijze van test zullen we elke 5 minuten een testbestand laten aanmaken in /var/tmp. Ga als volgt te werk:

Handeling met de muis.

  • Geef daarvoor de volgende regel in:

    0,5,10,15,20,25,30,35,40,45,50,55 * * * * touch /var/tmp/`date`
    
  • Als je klaar bent, druk je Ctrl+X.

  • Op de vraag of je de gemodificeerde buffer wilt bewaren, antwoord je met J.

  • Aanvaard de voorgestelde plaats om het bestand te bewaren door Enter te drukken.

  • Hiermee verlaat je de editor en kom je terug in de shell terecht. Je krijgt de boodschap:

    crontab: installing new crontab
    
[Opmerking]De /tmp map

De /tmp map is voorbehouden voor het systeem en de programma's die erop draaien. Bijvoorbeeld editors gebruiken ze om tijdelijke bestanden op te slaan. Je kan echter nakijken met ls /tmp dat het crontab commando het bestand onmiddellijk naar /var/spool/cron/crontabs/willy versluisd heeft.

Moet je zelf tijdelijk iets opslaan, bijvoorbeeld om iets af te halen van het Internet of om iets te testen, gebruik dan de map /var/tmp, die is voor dat doel voorbehouden. Deze scheiding is er omdat op vele systemen de map /tmp eigenlijk in het fysische geheugen zit, in plaats van dat het een map op de harde schijf is. Als je /tmp gebruikt op zo'n systemen, vul je dus eigenlijk het geheugen op en zal zo'n systeem sneller gaan swappen, wat voor enorme vertragingen kan zorgen. En als /tmp helemaal vol geraakt, kan dat voor vele programma's bovendien desastreuze gevolgen hebben. Op ons systeem loopt het niet direct zo'n vaart, maar je maakt er wel best een goede gewoonte van om je aan deze regel te houden. Zo kom je niet in de problemen wanneer je later op andere Linux of UNIX systemen gaat werken.

Gebruik het crontab -l commando om de crontab op het scherm te tonen:

Handeling met de muis.

willy@ubuntu:~$ crontab -l
0,5,10,15,20,25,30,35,40,45,50,55 * * * * touch "/var/tmp/`date`"

We zien hier een nieuwe shell constructie in de laatste kolom, waar we de uit te voeren opdracht weergeven. Het zijn de zogenaamde backticks of grave accenten. Alles wat daartussenstaat zal uitgevoerd worden als commando. Het date commando geeft de datum weer:

willy@ubuntu:~$ date
ma jun 23 12:04:21 CEST 2006

Omdat er ook een uuraanduiding met seconden in voorkomt, kunnen we op die manier elke vijf minuten een nieuwe bestandsnaam maken. Indien we bestandsnaam bij touch gewoon /var/tmp/date zouden opgeven, zouden we elke vijf minuten hetzelfde bestand opnieuw aanmaken.

Het tijdstip van uitvoering bepalen

Hoe weet cron nu wanneer een bepaalde taak uitgevoerd moet worden?

De cron daemon kijkt elke minuut alle crontabs en alle atjobs na. In de crontabs geef je het tijdstip op in de eerste vijf kolommen; zoals we reeds zagen volgt in de zesde kolom de uit te voeren opdracht. De kolommen hebben volgende betekenis:

  1. Eerste veld: de minuten na het uur waarop een taak uitgevoerd dient te worden. Mogelijke waarden zijn 0 tot en met 59.

  2. Tweede veld: het uur waarop een taak uitgevoerd moet worden. Mogelijke waarden zijn 0 tot en met 23.

  3. Derde veld: de dag van de maand waarop een taak moet uitgevoerd worden. Mogelijke waarden van 1 tot en met 31.

  4. Vierde veld: de maand van het jaar waarop een taak uitgevoerd moet worden. Mogelijke waarden van 1 tot en met 12.

  5. Vijfde veld: dag van de week waarop een taak uitgevoerd moet worden. Mogelijke waarden zijn van 0 tot en met 7, zowel 0 als 7 stellen zondag voor, zodanig dat er geen vergissingen kunnen optreden (maandag is altijd 1).

Gebruik het streepje om een doorlopende reeks op te geven, bijvoorbeeld 1-5 in het vijfde veld wil zeggen van maandag tot vrijdag.

Gebruik komma's om een onderbroken reeks op te geven, bijvoorbeeld zoals we net deden in het veld voor de minuten na het uur.

Gebruik een sterretje in het betreffende veld om aan te geven dat het commando uitgevoerd moet worden elke minuut, elk uur, elke dag, elke maand en/of elke dag van de week.

Een taak desactiveren

Om een taak niet meer uit te voeren, open je opnieuw de editor met het commando crontab -e. Je crontab kan uiteraard meerdere geautomatiseerde taken bevatten. Ga met de pijltjestoetsen naar de te verwijderen taak, en zet er een hekje voor (#), bijvoorbeeld ons testje:

Handeling met de muis.

# 0,5,10,15,20,25,30,35,40,45,50,55 * * * * touch "/var/tmp/`date`"

Verlaat de editor met Ctrl+X, antwoord met J en druk Enter.

Je zal de melding krijgen dat de crontab veranderd is. Doorgaans worden lijnen die beginnen met een hekje beschouwd als commentaar, maar ze worden niet door het programma, waarvoor ze bestemd zijn, ingelezen. Zo kan je een overzicht houden van veranderingen die je aan bestanden aanbrengt, of waarom je een bepaalde opdracht zus of zo hebt ingegeven. Op die manier kom je niet in de problemen wanneer je na lange tijd een configuratiebestand opnieuw moet editeren: je zal nog exact weten wat de bedoeling is als je er altijd voor zorgt om commentaar bij te schrijven.

Alternatief kan je natuurlijk ook gewoon de desbetreffende regel uit de crontab verwijderen en de crontab wegschrijven. Doe dit als je zeker bent dat je die taak niet meer zal moeten uitvoeren. Indien je ze nog wel ooit eens zal moeten uitvoeren, is het beter de commentaar-methode te gebruiken, dat bespaart typwerk op termijn.