Forstå og lære grunnleggende Shell-skripting og feilsøking av Linux-filsystem - del 10


Linux Foundation lanserte LFCS-sertifiseringen (Linux Foundation Certified Sysadmin), et helt nytt initiativ hvis formål er å la enkeltpersoner overalt (og hvor som helst) bli sertifisert i grunnleggende til middels operativ støtte for Linux-systemer, som inkluderer støtte for løpende systemer og tjenester, sammen med generell overvåking og analyse, pluss smart beslutningstaking når det gjelder å ta opp problemer til øvre støtteteam.

Sjekk ut følgende video som veileder deg en introduksjon til Linux Foundation Certification Program.

Dette er den siste artikkelen (del 10) i denne lange serien med 10 opplæringsprogrammer. I denne artikkelen vil vi fokusere på grunnleggende shell-scripting og feilsøking av Linux-filsystemer. Begge emnene kreves for LFCS-sertifiseringseksamenen.

Forstå terminaler og skjell

La oss avklare noen begreper først.

  1. Et skall er et program som tar kommandoer og gir dem til operativsystemet som skal utføres.
  2. En terminal er et program som lar oss som sluttbrukere samhandle med skallet. Et eksempel på en terminal er GNOME-terminal, som vist i bildet nedenfor.

Når vi først starter et skall, presenterer det en ledetekst (også kjent som kommandolinjen), som forteller oss at skallet er klart til å begynne å akseptere kommandoer fra standardinndataenheten, som vanligvis er tastaturet.

Det kan være lurt å referere til en annen artikkel i denne serien (Bruk kommando for å opprette, redigere og manipulere filer – del 1) for å se noen nyttige kommandoer.

Linux tilbyr en rekke alternativer for skjell, følgende er de vanligste:

bash Shell

Bash står for Bourne Again SHell og er GNU-prosjektets standardskall. Den inneholder nyttige funksjoner fra Korn-skallet (ksh) og C-skall (csh), og tilbyr flere forbedringer samtidig. Dette er standardskallet som brukes av distribusjonene som dekkes av LFCS-sertifiseringen, og det er skallet vi skal bruke i denne opplæringen.

sh Shell

Bourne SHell er det eldste skallet og har derfor vært standardskallet for mange UNIX-lignende operativsystemer i mange år.

ksh Shell

Korn SHell er et Unix-skall som ble utviklet av David Korn ved Bell Labs på begynnelsen av 1980-tallet. Den er bakoverkompatibel med Bourne-skallet og inkluderer mange funksjoner i C-skallet.

Et shell-script er intet mer eller intet mindre enn en tekstfil omgjort til et kjørbart program som kombinerer kommandoer som utføres av skallet etter hverandre.

Grunnleggende Shell-skripting

Som nevnt tidligere, er et shell-skript født som en ren tekstfil. Kan derfor opprettes og redigeres ved hjelp av vårt foretrukne tekstredigeringsprogram. Det kan være lurt å vurdere å bruke vi/m (se Bruk av vi Editor – del 2 av denne serien), som har syntaksutheving for enkelhets skyld.

Skriv inn følgende kommando for å lage en fil med navnet myscript.sh og trykk Enter.

vim myscript.sh

Den aller første linjen i et skallskript må være som følger (også kjent som en shebang).

#!/bin/bash

Den «forteller» operativsystemet navnet på tolken som skal brukes til å kjøre teksten som følger.

Nå er det på tide å legge til kommandoene våre. Vi kan klargjøre formålet med hver kommando, eller hele skriptet, ved å legge til kommentarer også. Merk at skallet ignorerer disse linjene som begynner med et pund-tegn # (forklarende kommentarer).

#!/bin/bash
echo This is Part 10 of the 10-article series about the LFCS certification
echo Today is $(date +%Y-%m-%d)

Når skriptet er skrevet og lagret, må vi gjøre det kjørbart.

chmod 755 myscript.sh

Før vi kjører skriptet vårt, må vi si noen ord om miljøvariabelen ` PATH. Hvis vi løper,

echo $PATH

fra kommandolinjen, vil vi se innholdet i ` PATH: en kolon-separert liste over kataloger som søkes når vi skriver inn navnet på et kjørbart program. Den kalles en miljøvariabel fordi den er en del av skallmiljøet – et sett med informasjon som blir tilgjengelig for skallet og dets underordnede prosesser når skallet først startes.

Når vi skriver en kommando og trykker Enter, søker skallet i alle katalogene som er oppført i ` PATH-variabelen og utfører den første forekomsten som blir funnet. La oss se et eksempel,

Hvis det er to kjørbare filer med samme navn, en i /usr/local/bin og en annen i /usr/bin, vil den i den første katalogen kjøres først, mens den andre vil bli ignorert.

Hvis vi ikke har lagret skriptet vårt i en av katalogene som er oppført i ` PATH-variabelen, må vi legge til ./ til filnavnet for å utføre den. Ellers kan vi kjøre det akkurat som vi ville gjort med en vanlig kommando.

pwd
./myscript.sh
cp myscript.sh ../bin
cd ../bin
pwd
myscript.sh

Betingelser

Når du trenger å spesifisere forskjellige handlinger som skal tas i et shell-skript, som et resultat av suksess eller fiasko for en kommando, vil du bruke hvis-konstruksjonen for å definere slike forhold. Dens grunnleggende syntaks er:

if CONDITION; then 
	COMMANDS;
else
	OTHER-COMMANDS 
fi

Hvor TILSTAND kan være en av følgende (bare de hyppigste tilstandene er sitert her) og evalueres til sann når:

  1. [ -en fil ] → fil finnes.
  2. [ -d fil ] → fil eksisterer og er en katalog.
  3. [ -f fil ] →fil finnes og er en vanlig fil.
  4. [ -u fil ] →filen eksisterer og dens SUID (sett bruker-ID) bit er satt.
  5. [ -g fil ] →filen eksisterer og dens SGID-bit er satt.
  6. [ -k fil ] →filen eksisterer og dens sticky bit er satt.
  7. [ -r fil ] →filen finnes og er lesbar.
  8. [ -s fil ]→ filen finnes og er ikke tom.
  9. [ -w fil ]→fil finnes og kan skrives.
  10. [ -x fil ] er sant hvis filen eksisterer og er kjørbar.
  11. [ streng1=streng2 ] → strengene er like.
  12. [ streng1 != streng2 ] →strengene er ikke like.

[ int1 op int2 ] skal være en del av den foregående listen, mens elementene som følger (for eksempel -eq –> er sant hvis int1 er lik int2.) skal være en «barn»-liste med [ int1 op int2 ] der op er en av følgende sammenligningsoperatører.

  1. -eq –> er sann hvis int1 er lik int2.
  2. -ne –> sann hvis int1 ikke er lik int2.
  3. -lt –> sann hvis int1 er mindre enn int2.
  4. -le –> sann hvis int1 er mindre enn eller lik int2.
  5. -gt –> sann hvis int1 er større enn int2.
  6. -ge –> sann hvis int1 er større enn eller lik int2.

For løkker

Denne sløyfen lar deg utføre en eller flere kommandoer for hver verdi i en liste med verdier. Dens grunnleggende syntaks er:

for item in SEQUENCE; do 
		COMMANDS; 
done

Hvor item er en generisk variabel som representerer hver verdi i SEQUENCE under hver iterasjon.

Mens Loops

Denne sløyfen gjør det mulig å utføre en rekke repeterende kommandoer så lenge kontrollkommandoen utføres med en utgangsstatus lik null (vellykket). Dens grunnleggende syntaks er:

while EVALUATION_COMMAND; do 
		EXECUTE_COMMANDS; 
done

Hvor EVALUATION_COMMAND kan være enhver kommando(er) som kan avsluttes med en vellykket (0) eller feil (annet enn 0) status, og EXECUTE_COMMANDS kan være et hvilket som helst program, skript eller skallkonstruksjon, inkludert andre nestede løkker.

Sette alt sammen

Vi vil demonstrere bruken av if-konstruksjonen og for-løkken med følgende eksempel.

Avgjøre om en tjeneste kjører i en systemd-basert distro

La oss lage en fil med en liste over tjenester som vi ønsker å overvåke med et øyeblikk.

cat myservices.txt

sshd
mariadb
httpd
crond
firewalld

Vårt skallskript skal se ut.

#!/bin/bash

This script iterates over a list of services and
is used to determine whether they are running or not.

for service in $(cat myservices.txt); do
    	systemctl status $service | grep --quiet "running"
    	if [ $? -eq 0 ]; then
            	echo $service "is [ACTIVE]"
    	else
            	echo $service "is [INACTIVE or NOT INSTALLED]"
    	fi
done

La oss forklare hvordan manuset fungerer.

1). For-løkken leser myservices.txt-filen ett element av LIST om gangen. Dette enkeltelementet er angitt med den generiske variabelen kalt tjeneste. LISTEN er fylt med utdata av,

cat myservices.txt

2). Kommandoen ovenfor er omsluttet av parentes og innledet med et dollartegn for å indikere at den bør evalueres for å fylle ut LIST som vi vil iterere over.

3). For hvert element i LIST (som betyr hver forekomst av tjenestevariabelen), vil følgende kommando bli utført.

systemctl status $service | grep --quiet "running"

Denne gangen må vi gå foran vår generiske variabel (som representerer hvert element i LIST) med et dollartegn for å indikere at det er en variabel, og derfor bør verdien i hver iterasjon brukes. Utgangen sendes deretter til grep.

–stille-flagget brukes for å forhindre at grep viser linjene der ordet kjører vises på skjermen. Når det skjer, returnerer kommandoen ovenfor en utgangsstatus på 0 (representert av $? i if-konstruksjonen), og bekrefter dermed at tjenesten kjører.

En utgangsstatus som er forskjellig fra 0 (som betyr at ordet som kjører ikke ble funnet i utdataene til systemctl status $service) indikerer at tjenesten ikke er løping.

Vi kan gå et skritt videre og sjekke om myservices.txt finnes før vi i det hele tatt prøver å gå inn i for-løkken.

#!/bin/bash

This script iterates over a list of services and
is used to determine whether they are running or not.

if [ -f myservices.txt ]; then
    	for service in $(cat myservices.txt); do
            	systemctl status $service | grep --quiet "running"
            	if [ $? -eq 0 ]; then
                    	echo $service "is [ACTIVE]"
            	else
                    	echo $service "is [INACTIVE or NOT INSTALLED]"
            	fi
    	done
else
    	echo "myservices.txt is missing"
fi
Pinger en serie nettverks- eller internettverter for svarstatistikk

Det kan være lurt å opprettholde en liste over verter i en tekstfil og bruke et skript for å finne ut nå og da om de er pingbare eller ikke (erstatt gjerne innholdet i myhosts og prøv selv ).

Den innebygde leseskall-kommandoen forteller while-løkken å lese myhosts linje for linje og tilordner innholdet i hver linje til variabel vert, som deretter sendes til ping-kommandoen.

#!/bin/bash

This script is used to demonstrate the use of a while loop

while read host; do
    	ping -c 2 $host
done < myhosts

Les også:

  1. Lær Shell-skripting: En guide fra nybegynnere til systemadministrator
  2. 5 Shell-skript for å lære Shell-programmering

Feilsøking av filsystem

Selv om Linux er et veldig stabilt operativsystem, hvis det krasjer av en eller annen grunn (for eksempel på grunn av strømbrudd), vil ikke ett (eller flere) av filsystemene dine bli demontert på riktig måte og vil derfor automatisk bli sjekket for feil når Linux startes på nytt.

I tillegg, hver gang systemet starter opp under en normal oppstart, sjekker det alltid integriteten til filsystemene før de monteres. I begge tilfeller utføres dette ved å bruke et verktøy kalt fsck ("filsystemsjekk ").

fsck vil ikke bare sjekke integriteten til filsystemer, men også forsøke å reparere korrupte filsystemer hvis du blir bedt om det. Avhengig av alvorlighetsgraden av skaden, kan fsck lykkes eller ikke; når den gjør det, blir gjenopprettede deler av filene plassert i tapt+funnet-katalogen, som ligger i roten til hvert filsystem.

Sist, men ikke minst, må vi merke oss at inkonsekvenser også kan skje hvis vi prøver å fjerne en USB-stasjon mens operativsystemet fortsatt skriver til den, og kan til og med føre til maskinvareskade.

Den grunnleggende syntaksen til fsck er som følger:

fsck [options] filesystem
Kontrollerer et filsystem for feil og forsøker å reparere automatisk

For å sjekke et filsystem med fsck, må vi først avmontere det.

mount | grep sdg1
umount /mnt
fsck -y /dev/sdg1

I tillegg til -y-flagget, kan vi bruke -a-alternativet til å reparere filsystemene automatisk uten å stille noen spørsmål, og tvinge kontrollen selv når filsystemet ser rent ut.

fsck -af /dev/sdg1

Hvis vi bare er interessert i å finne ut hva som er galt (uten å prøve å fikse noe foreløpig) kan vi kjøre fsck med -n-alternativet, som vil sende ut filsystemproblemene til standardutdata.

fsck -n /dev/sdg1

Avhengig av feilmeldingene i utdataene til fsck, vil vi vite om vi kan prøve å løse problemet selv eller eskalere det til ingeniørteam for å utføre ytterligere kontroller av maskinvaren.

Sammendrag

Vi har kommet til slutten av denne 10-artikkel-serien hvor vi har forsøkt å dekke de grunnleggende domenekompetansene som kreves for å bestå LFCS-eksamenen.

Av åpenbare grunner er det ikke mulig å dekke hvert enkelt aspekt av disse emnene i en enkelt veiledning, og det er derfor vi håper at disse artiklene har satt deg på rett spor for å prøve nye ting selv og fortsette å lære.

Hvis du har spørsmål eller kommentarer, er de alltid velkomne - så ikke nøl med å sende oss en linje via skjemaet nedenfor!