
Als een Linux Bash-script erop vertrouwt dat bepaalde bestanden of mappen aanwezig zijn, kan het niet zomaar aannemen dat dit het geval is. Het moet controleren of ze zeker aanwezig zijn. Hier is hoe dat te doen.
Veronderstel niets
Als je een script schrijft, mag je geen aannames doen over wat wel en niet aanwezig is op een computer. Dat is dubbel waar als het script op veel verschillende computers wordt gedistribueerd en uitgevoerd. Vroeg of laat zal het script worden uitgevoerd op een computer die niet aan uw veronderstellingen voldoet, en het script zal mislukken of onvoorspelbaar worden uitgevoerd.
Alles wat we waarderen of creëren op een computer, wordt opgeslagen in een bestand van een bepaald formaat en al die bestanden bevinden zich in een map. Scripts kunnen bestanden en mappen lezen, schrijven, hernoemen, verwijderen en verplaatsen – alles wat u op de opdrachtregel kunt doen.
Het voordeel dat je als mens hebt, is dat je de inhoud van een map kunt zien en weet of een bestand bestaat of niet, of dat de verwachte map zelfs bestaat. Als een script een fout maakt bij het manipuleren van bestanden, kan dit ernstige en schadelijke gevolgen hebben.
Bash biedt een uitgebreide reeks tests die u kunt gebruiken om bestanden en mappen te detecteren en op veel van hun kenmerken te testen. Het is eenvoudig om deze in scripts op te nemen, maar de voordelen op het gebied van robuustheid en fijne controle zijn aanzienlijk.
Het bereik van tests
Door de if-instructie te combineren met de juiste test uit een grote verzameling bestands- en directorytests, kunnen we eenvoudig bepalen of een bestand bestaat, of het uitvoerbaar of beschrijfbaar is, en nog veel meer.
- -b: Retourneert waar als het bestand een speciaal blokbestand is.
- -c: Retourneert waar als het bestand een speciaal teken is.
- -d: Retourneert waar als het “bestand” een map is.
- -e: Retourneert waar als het bestand bestaat.
- -f: Retourneert waar als het bestand bestaat en een normaal bestand is.
-
-g: Retourneert waar als het bestand de heeft
setgidmachtigingenset (chmod g+). - -h: Retourneert waar als het bestand een symbolische koppeling is.
- -L: Retourneert waar als het bestand een symbolische koppeling is.
-
-k: Retourneert waar als zijn kleverige bit is ingesteld (
chmod +t). - -p: Retourneert waar als het bestand een benoemde pijp is.
- -r: Retourneert waar als het bestand leesbaar is.
- -s: Retourneert waar als de bestanden bestaan en is niet leeg.
- -S: Retourneert waar als het bestand een socket is.
- -t: Retourneert waar als de bestandsdescriptor in een terminal wordt geopend.
-
-u: Retourneert waar als het bestand de heeft
setuidmachtigingenset (chmod u+). - -w: Retourneert waar als het bestand beschrijfbaar is.
- -x: Retourneert waar als het bestand uitvoerbaar is.
- -O: Retourneert waar als het uw eigendom is.
- -G: Retourneert waar als het eigendom is van uw groep.
- -N: Retourneert waar als het bestand is gewijzigd sinds het voor het laatst is gelezen.
- !: De logische NOT-operator.
- &&: De logische AND-operator.
- ||: De logische OR-operator.
De lijst begint met -b omdat de -a test is verouderd en vervangen door de -e testen.
De tests in scripts gebruiken
De generieke bestandstest if statement is een eenvoudige scriptconstructie. De vergelijking tussen de dubbele haakjes ” [[ ]] ” gebruikt de -f test om te bepalen of er een normaal bestand met die naam bestaat.
Kopieer de tekst van dit script naar een editor en sla het op in een bestand met de naam “script1.sh”, en gebruik chmod om het uitvoerbaar te maken.
#!/bin/bash if [[ -f $1 ]] then echo "The file $1 exists." else echo "The file $1 cannot be found." fi
U moet de naam van het bestand doorgeven aan het script op de opdrachtregel.
chmod +x script1.sh

U moet dit bij elk script doen als u de andere voorbeelden uit het artikel wilt proberen.
Laten we het script proberen op een eenvoudig tekstbestand.
./script1.sh test-file.txt

Het bestand bestaat en het script meldt dat feit correct. Als we het bestand verwijderen en het opnieuw proberen, zou de test moeten mislukken en zou het script dat aan ons moeten rapporteren.
./script1.sh test-file.txt

In een echte situatie zou uw script de juiste actie moeten ondernemen. Misschien markeert het de fout en stopt het. Misschien maakt het het bestand aan en gaat het verder. Het kan iets uit een back-upmap kopiëren om het ontbrekende bestand te vervangen. Het hangt allemaal af van het doel van het script. Maar nu kan het script in ieder geval de beslissing nemen op basis van weten of het bestand aanwezig is of niet.
De -f flag test of het bestand aanwezig is, en een “normaal” bestand is. Met andere woorden, het is niet iets dat een bestand lijkt te zijn, maar het niet is, zoals een apparaatbestand.
We zullen ls gebruiken om te verifiëren dat het bestand “/dev/random” bestaat, en dan kijken wat het script ervan maakt.
ls -lh /dev/random
./script /dev/random

Omdat ons script op reguliere bestanden test en “/dev/random” een apparaatbestand is, mislukt de test. Heel vaak, om tot op de bodem uit te zoeken of een bestand bestaat, moet je zorgvuldig kiezen welke test je gebruikt, of je moet meerdere tests gebruiken.
Dit is “script2.sh”, dat test op gewone bestanden en op tekenapparaatbestanden.
#!/bin/bash if [[ -f $1 ]] then echo "The file $1 exists." else echo "The file $1 is missing or not a regular file." fi if [[ -c $1 ]] then echo "The file $1 is a character device file." else echo "The file $1 is missing or not a special file." fi
Als we dit script uitvoeren op het apparaatbestand “/dev/random” mislukt de eerste test die we verwachten, en de tweede test slaagt. Het herkent het bestand als een apparaatbestand.
./script2.sh /dev/random

Eigenlijk herkent het het als een karakter apparaat bestand. Sommige apparaatbestanden zijn blokapparaatbestanden. Zoals het er nu uitziet, zal ons script daar niet tegen kunnen.
./script2.sh /dev/sda

We kunnen gebruik maken van de logische OR operator en neem nog een test op in de tweede if-instructie. Deze keer, of het bestand een tekenapparaatbestand is of een blokapparaatbestand, zal de test true retourneren. Dit is “script3.sh.”
#!/bin/bash if [[ -f $1 ]] then echo "The file $1 exists." else echo "The file $1 is missing or not a regular file." fi if [[ -c $1 || -b $1 ]] then echo "The file $1 is a character or block device file." else echo "The file $1 is missing or not a special file." fi
Dit script herkent zowel character device- als block device-bestanden.
./script3.sh /dev/random
./script3.sh /dev/sda

Als het belangrijk voor u is om onderscheid te maken tussen de verschillende soorten apparaatbestanden, kunt u genest if verklaringen. Dit is “script4.sh.”
#!/bin/bash if [[ -f $1 ]] then echo "The file $1 exists." else echo "The file $1 is missing or not a regular file." fi if [[ -c $1 ]] then echo "The file $1 is a character device file." else if [[ -b $1 ]] then echo "The file $1 is a block device file." else echo "The file $1 is missing or not a device file." fi fi
Dit script herkent en categoriseert zowel character device- als block device-bestanden.
./script4.sh /dev/random
./script4.sh /dev/sda

Met behulp van de logische AND-operator kunnen we op verschillende kenmerken tegelijk testen. Dit is “script5.sh.” Het controleert of een bestand bestaat en het script heeft gelezen en schrijfrechten ervoor.
#!/bin/bash if [[ -f $1 && -r $1 && -w $1 ]] then echo "The file $1 exists and we have read/write permissions." else echo "The file $1 is missing, not a regular file, or we can't read/write to it." fi
We zullen het script uitvoeren op een bestand dat van ons is, en een bestand dat toebehoort aan root.
./script5.sh .bashrc
./script5.sh /etc/fstab

Om te testen op het bestaan van een directory, gebruik de -d testen. Dit is “script6.sh.” Het maakt deel uit van een back-upscript. Het eerste dat het doet, is controleren of de map die op de opdrachtregel is doorgegeven, bestaat of niet. Het gebruikt de logische NOT operator ! in de if verklaring testen.
#!/bin/bash if [[ ! -d $1 ]] then echo "Creating backup directory:" $1 mkdir $1 if [[ ! $? -eq 0 ]] then echo "Couldn't create backup directory:" $1 exit fi else echo "Backup directory exists." fi # continue with file backup echo "Backing up to: "$1
Als de map niet bestaat, wordt deze gemaakt. Als de directory-aanmaakbestanden worden gemaakt, wordt het script afgesloten. Als het aanmaken van de directory lukt, of als de directory al bestaat, gaat het script verder met zijn back-upacties.
We zullen het script uitvoeren en dan controleren met ls en de -d (directory) optie of de back-updirectory bestaat.
./script6.sh Documents/project-backup
ls -d Documents/project-backup

De back-upmap is gemaakt. Als we het script opnieuw uitvoeren, zou het moeten melden dat de map al aanwezig is.
./script6.sh

Het script vindt de map en gaat verder met het uitvoeren van de back-up.
Testen, niet aannemen
Vroeg of laat zullen veronderstellingen ertoe leiden dat er slechte dingen gebeuren. Eerst testen en dienovereenkomstig reageren.
Kennis is macht. Gebruik tests om uw scripts de kennis te geven die ze nodig hebben.