Naar inhoud springen

Shellscript

Uit Wikipedia, de vrije encyclopedie

Een shellscript is een script dat is geschreven voor de shell ofwel de interpreter van de commandoregel. Het wordt vaak beschouwd als een relatief eenvoudige programmeertaal die toegespitst is op systeembeheer. Typische operaties die door shellscripts worden uitgevoerd omvatten bestandsmanipulatie, het uitvoeren van programma's en tekst afdrukken. Normaliter verwijst de term shellscript naar scripts die voor een Unixshell zijn geschreven, terwijl de term batchbestand meestal verwijst naar andere besturingssystemen.

In de regel is een shellscript een file (of bestand) met (één of meer) shellcommando's.

In hun meest basale vorm kunnen shellscripts worden gebruikt om diverse commando's automatisch en snel uit te laten voeren. Door het aanroepen van zo'n shellscript vervalt de noodzaak om al die commando's "met de hand" op de commandoregel te moeten intypen. In het volgende voorbeeld worden alle MP3-bestanden (*.mp3) in de homedirectory van de gebruiker verplaatst naar de directory 'MP3':

mv ~/*.mp3 MP3

Dit voorbeeld laat zien:

  • met welk commando files worden verplaatst ('mv')
  • dat de homedirectory wordt aangeduid door middel van het teken "~"
  • dat directory's van elkaar worden gescheiden door het teken "/"
  • hoe het jokerteken "*" wordt gebruikt om gerelateerde files te matchen
  • dat de directory "MP3" zich in de huidige (werk)directory bevindt

De meeste shells hebben de mogelijkheid om door middel van patronen (bv. jokertekens) files aan te kunnen duiden of te selecteren, waardoor er operaties op een selectie van files kan worden uitgevoerd. Het volgende voorbeeld laat zien hoe in een 'for'-lus steeds een andere filenaam wordt toegekend aan de variabele 'filenaam':

for filenaam in *.mp3; do ...; done

Merk op dat alleen filenamen worden geselecteerd die eindigen op '.mp3'.

Een variabele wordt vaak gebruikt om een naam toe te kennen aan een bepaalde waarde en die waarde te bewaren in de benoemde variabele. De waarde van de variabele kan vervolgens (tijdens het uitvoeren van een shellscript) worden gesubstitueerd op elke plaats waar die variabele wordt gebruikt in het shellscript.

Ook bieden moderne shells de mogelijkheid om operaties uit te voeren op stukken tekst. Het volgende voorbeeld laat zien hoe de volledige padnaam (bv. /etc/passwd) van een file, behalve de filenaam zelf, wordt onderdrukt en in een variabele 'base' wordt opgeslagen:

base=${filenaam##*/} # variabele $filenaam bevat de volledige padnaam

Merk op dat alle tekst vanaf het teken '#' (na de spatie!) als commentaar wordt opgevat.

Om een combinatie van mogelijkheden te tonen, volgt hier het hernoemen van alle filenamen die op '.mpg' eindigen:

for naam in *.mpg; do
 mv "$naam" "${naam%%.mpg}.mpeg" # hernoem file.mpg naar file.mpeg
done

Bovenstaand voorbeeld laat tevens zien hoe een bestandsextensie (of -suffix) kan worden verwijderd en er een nieuwe suffix aan kan worden vastgeplakt.

Het bovenstaande scriptje kan ook op één regel worden geschreven als:

for naam in *.mpg; do mv "$naam" "${naam%%.mpg}.mpeg"; done # hernoem *.mpg

Indien men echter ook filenamen met een andere suffix wil hernoemen, zal het script moeten worden bewerkt. Het is tamelijk bewerkelijk om dit steeds opnieuw te moeten doen indien dit script zich in een file bevindt. Uiteindelijk is het een beter plan om dit op een permanentere manier op te lossen in een shellscript:

for naam in *.$1; do mv "$naam" "${naam%%.$1}.$2"; done

Dit voorbeeld toont aan dat scripttalen (zoals shellscripts) ook speciale variabelen ondersteunen die toegang verschaffen tot de argumenten die aan een programma kunnen worden meegegeven op de commandoregel. Zo geven de variabelen $1 tot en met $9 toegang tot de eerste negen argumenten van een shellscript. Zo kan het onderhavige shellscript dat de speciale variabelen $1 en $2 bevat, worden aangeroepen met de twee argumenten 'txt' en 'text' om alle filenamen die eindigen op '.txt' te hernoemen en in plaats daarvan op '.text' te laten eindigen.

Er dient te worden opgemerkt dat er onderscheid dient te worden gemaakt tussen variabelen binnen (het proces van) een shellscript en (globale) omgevingsvariabelen die bekend zijn bij de shell van het besturingssysteem. De shell 'erft' normaliter niet (de waarden van) de variabelen die in een shellscript zijn gebruikt: zodra een script is uitgevoerd, zijn de in het shellscript gebruikte variabelen niet langer bereikbaar. Om een variabele in een shellscript te 'exporteren' naar de shell van de gebruiker kunnen enkele trucs worden toegepast:

  • het laten genereren van output door het shellscript
    • en die output laten opvangen door de shell (met behulp van backquotes), of
    • de output laten opvangen via het (filterende) 'pipe-mechanisme' van de shell, of
    • de output wegschrijven naar een file
  • het 'source-mechanisme' van de shell gebruiken
    • bij een Bourne-shellachtige is dat het commando "."
    • bij een Csh-achtige shell is dat het commando "source"

Shellscripts kunnen ook een 'exitcode' of 'returncode', een bepaalde numerieke waarde, teruggeven nadat het shellscript is beëindigd. Deze exitcode kan aangeven dat het programma succesvol verliep (exitcode 0) of dat het uitvoeren ervan op de één of andere manier een fout opleverde (bij een andere exitcode dan 0). Zo is het mogelijk om een programma slechts uit te voeren indien een voorgaand programma met succes verliep. Een voorbeeld met twee programma's, genaamd 'a' en 'b':

a && b

Hier wordt eerst programma 'a' uitgevoerd en indien dat succesvol verliep (dat wil dus zeggen dat 'a' returncode 0 gaf), dan wordt vervolgens 'b' uitgevoerd.

Door het gebruik van 'control-flow'-constructies (zoals "if", "while" en "for"), variabelen en subroutines ('functions') kunnen gestructureerde shellscripts worden geschreven. Deze scripts kunnen vervolgens in een groter geheel (bv. binnen een applicatie) worden opgenomen. Natuurlijk vergen systemen of programma's met hoge, complexe eisen meestal krachtigere programmeertalen, hoewel shells op hun manier ook kracht en flexibiliteit hebben, maar geïnterpreteerd moeten worden, wat vaak snelheidsverlies betekent.

Andere scripttalen

[bewerken | brontekst bewerken]

Voor operaties die te omvangrijk of te complex zijn om door simpele shellscripts te worden afgehandeld, maar waarbij het voordelig is om toch een vorm van een scripttaal te gebruiken in plaats van de overhead bij het compileren van een programma, zijn er veel andere, krachtige scripttalen ontwikkeld. Twee voorbeelden van zulke scripttalen zijn AWK en Perl. Het is overigens gewoon mogelijk om AWK- en Perl-scripts te integreren in shellscripts.