
Als je begint met Bash-scripting op Linux, zal een goed begrip van de basisprincipes je goed van pas komen. Ze vormen de basis van diepere kennis en hogere scriptvaardigheden.
Onthoud, maak uw scripts uitvoerbaar
Om de shell een script te laten uitvoeren, moet het script de machtigingenset voor het uitvoerbare bestand hebben. Zonder dit is uw script slechts een tekstbestand. Hiermee is het nog steeds een tekstbestand, maar de shell weet dat het instructies bevat en zal proberen deze uit te voeren wanneer het script wordt gestart.
Het hele punt van het schrijven van scripts is dat ze worden uitgevoerd, dus de eerste basisstap is om te weten hoe je Linux kunt laten weten dat je script als uitvoerbaar moet worden beschouwd.
De chmod commando laat ons bestandsrechten instellen. De execute-permissie kan worden ingesteld met de vlag +x.
chmod +x script1.sh

U moet dit voor elk van uw scripts doen. Vervang “script1.sh” door de naam van uw script.
1. Wat is die vreemde eerste regel?
De eerste regel van een script vertelt de shell welke interpreter moet worden aangeroepen om dat script uit te voeren. De eerste regel moet beginnen met een shebang, “#!”, ook bekend als een hashbang. De “#!” vertelt de shell dat deze regel het pad en de naam bevat van de interpreter waarvoor het script is geschreven.
Dit is belangrijk, want als je een script hebt geschreven dat in Bash moet worden uitgevoerd, wil je niet dat het door een andere shell wordt geïnterpreteerd. Er zijn waarschijnlijk onverenigbaarheden. Bash heeft, zoals de meeste shells, zijn eigen eigenaardigheden van syntaxis en functionaliteit die andere shells niet zullen hebben, of anders zullen hebben geïmplementeerd.
Wanneer u een script uitvoert, opent de huidige shell het script en bepaalt welke shell of interpreter moet worden gebruikt om dat script uit te voeren. Het lanceert vervolgens die shell en geeft het script eraan door.
#!/bin/bash echo Running in $SHELL
De eerste regel van dit script kan worden gelezen als “Gebruik de interpreter op /bin/bash om dit script uit te voeren.”
De enige regel in het script schrijft de waarde in de $SHELL omgevingsvariabele naar het terminalscherm. Dit bevestigt dat Bash is gebruikt om het script uit te voeren.
./script1.sh

Als een beetje een salontruc kunnen we aantonen dat het script wordt doorgegeven aan elke tolk die we selecteren.
#!/bin/cat All the lines of text are passed to the cat command and are printed in the terminal window. That includes the shebang line.
script2.sh

Dit script wordt gestart door de huidige shell en doorgegeven aan de cat opdracht. De cat commando “voert” het script uit.
Als je je shebangs op deze manier schrijft, ga je ervan uit dat je weet waar de shell of andere interpreter zich op de doelmachine bevindt. En 99% van de tijd is dat prima. Maar sommige mensen houden ervan om hun weddenschappen af te dekken en schrijven hun krengen als volgt:
#!/usr/bin/env bash echo Running in $SHELL
script3.sh

Wanneer het script wordt gestart, wordt de shell zoekopdrachten voor de locatie van de genoemde shell. Als de shell zich op een niet-standaard locatie bevindt, kan dit type benadering “slechte interpreter” -fouten voorkomen.
Luister niet, hij liegt!
In Linux is er altijd meer dan één manier om een kat te villen of te bewijzen dat een auteur ongelijk heeft. Om volledig feitelijk te zijn, is er een manier om scripts uit te voeren zonder poespas en zonder ze uitvoerbaar te maken.
Als u de shell start waarop u het script wilt uitvoeren en het script doorgeeft als een opdrachtregelparameter, zal de shell het script starten en uitvoeren, of het nu uitvoerbaar is of niet. Omdat je de shell op de opdrachtregel kiest, is er geen noodzaak voor een shebang.
Dit is het hele script:
echo "I've been executed by" $SHELL
We gebruiken ls om te zien dat het script echt niet uitvoerbaar is en start Bash met de naam van het script:
ls
bash script4.sh

Er is ook een manier om een script te laten uitvoeren door de huidig shell, niet een shell die speciaal is gelanceerd om het script uit te voeren. Als u de source commando, dat kan worden afgekort tot een enkele punt “.“, uw script wordt uitgevoerd door uw huidige shell.
Dus, om een script uit te voeren zonder een shebang, zonder de uitvoerbare bestandspermissie, en zonder een andere shell te starten, kun je een van deze commando’s gebruiken:
source script4.sh
. script4.sh

Hoewel dit mogelijk is, wordt het niet aanbevolen als algemene oplossing. Er zijn nadelen.
Als een script geen shebang bevat, kun je niet zien voor welke shell het is geschreven. Ga je het over een jaar onthouden? En zonder dat de uitvoerbare toestemming voor het script is ingesteld, is de ls commando zal het niet identificeren als een uitvoerbaar bestand, en het zal ook geen kleur gebruiken om het script te onderscheiden van platte tekstbestanden.
2. Tekst afdrukken
Het schrijven van tekst naar de terminal is een veelvoorkomende vereiste. Een beetje visuele feedback gaat een lange weg.
Voor eenvoudige berichten, de echo bevel zal volstaan. Het staat enige opmaak van de tekst toe en laat je ook met variabelen werken.
#!/bin/bash echo This is a simple string. echo "This is a string containing 'single quotes' so it's wrapped in double quotes." echo "This prints the user name:" $USER echo -e "The -e option lets us usenformatting directivesnto split the string."
./script5.sh

De printf commando geeft ons meer flexibiliteit en betere opmaakmogelijkheden, inclusief nummerconversie.
Dit script drukt hetzelfde nummer af met drie verschillende numerieke bases. De hexadecimale versie is ook opgemaakt om in hoofdletters te worden afgedrukt, met voorloopnullen en een breedte van drie cijfers.
#!/bin/bash printf "Decimal: %d, Octal: %o, Hexadecimal: %03Xn" 32 32 32
./script6.sh

Merk op dat in tegenstelling tot met echomoet je vertellen printf om een nieuwe regel te beginnen met de “n” teken.
3. Variabelen maken en gebruiken
Met variabelen kunt u waarden in uw programma opslaan en manipuleren en gebruiken. U kunt uw eigen variabelen maken of omgevingsvariabelen gebruiken voor systeemwaarden.
#!/bin/bash millennium_text="Years since the millennium:" current_time=$( date '+%H:%M:%S' ) todays_date=$( date '+%F' ) year=$( date '+%Y' ) echo "Current time:" $current_time echo "Today's date:" $todays_date years_since_Y2K=$(( year - 2000 )) echo $millennium_text $years_since_Y2K
Dit script maakt een stringvariabele aan met de naam millennium_text. Het bevat een regel tekst.
Vervolgens worden drie numerieke variabelen gemaakt.
- De
current_timevariabele wordt geïnitialiseerd op het moment dat het script wordt uitgevoerd. - De
todays_datevariabele is ingesteld op de datum waarop het script wordt uitgevoerd. - De
yearvariabele bevat het huidige jaar.
Om toegang te krijgen tot de waarde opgeslagen in een variabele, laat de naam voorafgaan door een dollarteken “$”.
./script7.sh

Het script drukt de tijd en datum af, berekent vervolgens hoeveel jaar er zijn verstreken sinds het millennium en slaat dit op in de years_since_Y2K variabel.
Ten slotte drukt het de tekenreeks af die is opgenomen in de millennium_text variabele en de numerieke waarde die is opgeslagen in de years_since_Y2K.
4. Gebruikersinvoer verwerken
Om een gebruiker toe te staan een waarde in te voeren die het script zal gebruiken, moet u de toetsenbordinvoer van de gebruiker kunnen vastleggen. De bash read commando staat u toe om precies dat te doen. Hier is een eenvoudig voorbeeld.
#!/bin/bash echo "Enter a number and hit "Enter"" read user_number1; echo "Enter another number and hit "Enter"" read user_number2; printf "You entered: %d and %dn" $user_number1 $user_number2 printf "Added together they make: %dn" $(( user_number1 + user_number2))
Het script vraagt om twee cijfers. Ze worden gelezen vanaf het toetsenbord en opgeslagen in twee variabelen, user_number1 en user_number2 .
Het script drukt de getallen af naar het terminalvenster, telt ze bij elkaar op en drukt het totaal af.
./script8.sh

We kunnen de prompts combineren in de read commando’s met de -p (prompt) optie.
#!/bin/bash read -p "Enter a number and hit "Enter" " user_number1; read -p "Enter another number and hit "Enter" " user_number2; printf "You entered: %d and %dn" $user_number1 $user_number2 printf "Added together they make: %dn" $(( user_number1 + user_number2))
Dit maakt de zaken overzichtelijker en gemakkelijker te lezen. Scripts die gemakkelijk te lezen zijn, zijn ook gemakkelijker te debuggen.
./script9.sh

Het script gedraagt zich nu iets anders. De gebruikersinvoer bevindt zich op dezelfde regel als de prompt.
Om toetsenbordinvoer vast te leggen zonder deze naar het terminalvenster te laten echoën, gebruikt u de -s (stille) optie.
#!/bin/bash read -s -p "Enter your secret PIN and hit "Enter" " secret_PIN; printf "nShhh ... it is %dn" $secret_PIN
./script10.sh

De invoerwaarde wordt vastgelegd en opgeslagen in een variabele genaamd secret_PIN maar het wordt niet op het scherm weergegeven wanneer de gebruiker typt het. Wat je er daarna mee doet, is aan jou.
5. Parameters accepteren
Soms is het handiger om gebruikersinvoer te accepteren als opdrachtregelparameters dan om een script te laten wachten op invoer. Het doorgeven van waarden aan een script is eenvoudig. Er kan in het script naar worden verwezen alsof het een andere variabele is.
De eerste parameter wordt variabel $1de tweede parameter wordt variabel $2, enzovoort. Variabele $0 bevat altijd de naam van het script, en variabele $# bevat het aantal parameters dat op de opdrachtregel is opgegeven. Variabele $@ is een tekenreeks die alle opdrachtregelparameters bevat.
#!/bin/bash printf "This script is called: %sn" $0 printf "You used %d command line parametersn" $# # loop through the variables for param in "$@"; do echo "$param" done echo "Parameter 2 was:" $2
Dit script gebruikt $0 en $# om wat informatie af te drukken. gebruikt dan ?@ om alle opdrachtregelparameters te doorlopen. Het gebruikt $2 om te laten zien hoe u toegang krijgt tot een enkele, bepaalde parameterwaarde.
./script11.sh

Door meerdere woorden tussen aanhalingstekens “”” te plaatsen, worden ze gecombineerd tot één enkele parameter.
6. Gegevens uit bestanden lezen
Weten hoe u gegevens uit een bestand moet lezen, is een geweldige vaardigheid om te hebben. We kunnen dit in Bash doen met een while-lus.
#!/bin/bash
LineCount=0
while IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; do
((LineCount++))
echo "Reading line $LineCount: ${LinefromFile}"
done < "$1"
We geven de naam door van het bestand dat we door het script willen laten verwerken als een opdrachtregelparameter. Het zal de enige parameter zijn, dus in het script $1 zal de bestandsnaam bevatten. We leiden dat bestand om naar de while lus.
De while loop stelt het interne veldscheidingsteken in op een lege tekenreeks, met behulp van de IFS='' opdracht. Dit voorkomt dat de read commando van het splitsen van regels op witruimte. Alleen de regelterugloop aan het einde van een regel wordt als het ware einde van de regel beschouwd.
De [[ -n "${LinefromFile}" ]] clausule voorziet in de mogelijkheid dat de laatste regel in het bestand niet eindigt met een regelterugloop. Zelfs als dit niet het geval is, wordt die laatste regel correct afgehandeld en behandeld als een normale POSIX-compatibele regel.
./script12.sh twinkle.txt

7. Voorwaardelijke tests gebruiken
Als u wilt dat uw script verschillende acties uitvoert voor verschillende voorwaarden, moet u voorwaardelijke tests uitvoeren. De testsyntaxis met dubbele haakjes levert een aanvankelijk overweldigend aantal opties op.
#!/bin/bash price=$1 if [[ price -ge 15 ]]; then echo "Too expensive." else echo "Buy it!" fi
Bash biedt een hele reeks vergelijkingsoperatoren waarmee je dingen kunt bepalen, zoals of een bestand bestaat, of je ervan kunt lezen, of je ernaar kunt schrijven en of een map bestaat.
Het heeft ook numerieke tests voor gelijken -qegroter dan -gtMinder dan of gelijk -leenzovoort, hoewel u ook de bekende . kunt gebruiken == , >= , <= notatie.
./script13.sh 13
./script13.sh 14
./script13.sh 15
./script13.sh 16

8. De kracht van for-loops
Het steeds opnieuw herhalen van acties kan het beste worden bereikt met behulp van lussen. EEN for lus laat je een lus een aantal keren uitvoeren. Dit kan tot een bepaald aantal zijn, of het kan zijn totdat de lus zich een weg heeft gebaand door een lijst met items.
#!/bin/bash
for (( i=0; i<=$1; i++ ))
do
echo "C-style for loop:" $i
done
for i in {1..4}
do
echo "For loop with a range:" $i
done
for i in "zero" "one" "two" "three"
do
echo "For loop with a list of words:" $i
done
website="How To Geek"
for i in $website
do
echo "For loop with a collection of words:" $i
done
Al deze lussen zijn for lussen, maar ze werken met verschillende soorten lusinstructies en gegevens.
./script14.sh 3

De eerste lus is een klassieke C-stijl for lus. De lusteller i wordt geïnitialiseerd op nul en verhoogd met elke cyclus van de lus. Terwijl de waarde van i is kleiner dan of gelijk aan de waarde aangehouden in $1blijft de lus lopen.
De tweede lus werkt door het bereik van getallen van 1 tot 4. De derde lus werkt door een lijst met woorden. Hoewel er meer woorden moeten worden verwerkt, blijft de lus zich herhalen.
De laatste lus werkt door de lijst met woorden in een stringvariabele.
9. Functies
Met functies kunt u delen van code inkapselen in benoemde routines die overal in uw script kunnen worden aangeroepen.
Stel dat we wilden dat ons script dat regels uit een bestand leest een soort verwerking op elke regel zou doen. Het zou handig zijn om die code in een functie te hebben.
#!/bin/bash
LineCount=0
function count_words() {
printf "%d words in line %dn" $(echo $1 | wc -w) $2
}
while IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; do
((LineCount++))
count_words "$LinefromFile" $LineCount
done < "$1"
count_words "This isn't in the loop" 99
We hebben ons programma voor het lezen van bestanden aangepast door een functie toe te voegen met de naam count_words. Het is gedefinieerd voordat we moeten het gebruiken.
De functiedefinitie begint met het woord function. Dit wordt gevolgd door een unieke naam voor onze functie gevolgd door haakjes “().” De hoofdtekst van de functie staat tussen accolades “{}.”
De functiedefinitie zorgt ervoor dat er geen code wordt uitgevoerd. Niets in de functie wordt uitgevoerd totdat de functie wordt aangeroepen.
De count_words functie drukt het aantal woorden in een regel tekst en het regelnummer af. Deze twee parameters worden aan de functie doorgegeven, net zoals parameters aan een script worden doorgegeven. De eerste parameter wordt functie variabele $1en de tweede parameter wordt functievariabele $2enzovoort.
De while lus leest elke regel uit het bestand en geeft deze door aan de count_words functie, samen met het regelnummer. En om te laten zien dat we de functie vanuit verschillende plaatsen in het script kunnen aanroepen, noemen we hem nog een keer buiten de while lus.
./script15.sh twinkle.txt

Wees niet bang voor de leercurve
Scripting is lonend en nuttig, maar moeilijk om erin te komen. Als je eenmaal wat herbruikbare technieken onder je riem hebt gekregen, kun je relatief eenvoudig waardevolle scripts schrijven. Dan kun je kijken naar meer geavanceerde functionaliteit.
Loop voordat je kunt rennen en neem de tijd om van de reis te genieten.