Cum să utilizați testele condiționate cu paranteze duble în Linux

Publicat: 2022-01-29
fatmawati achmad zaenuri/Shutterstock.com

Testele condiționate ramifică fluxul de execuție al scripturilor Linux Bash în funcție de rezultatul unei expresii logice. Testele condiționate cu paranteze duble simplifică considerabil sintaxa, dar au totuși propriile lor probleme.

Paranteze simple și duble

Bash oferă comanda de test . Aceasta vă permite să testați expresii logice. Expresia va returna un răspuns care indică un răspuns adevărat sau fals. Un răspuns adevărat este indicat printr-o valoare returnată de zero. Orice altceva decât zero indică fals.

Înlănțuirea comenzilor pe linia de comandă cu operatorul && utilizează această caracteristică. Comenzile sunt executate numai dacă comanda anterioară se finalizează cu succes.

Dacă testul este adevărat, va fi tipărit cuvântul „Da”.

 test 15 -eq 15 && eco „Da”
 test 14 -eq 15 && ecou „Da” 

Exemple simple ale comenzii de testare Bash

Testele condiționale cu o singură paranteză imită comanda de test . Acestea înfășoară expresia între paranteze „ [ ] ” și funcționează la fel ca comanda de test . De fapt, sunt același program, creat din același cod sursă. Singura diferență operațională este modul în care versiunea de test și [ versiunea gestionează cererile de ajutor.

Acesta este din codul sursă:

 /* Recunoaște --help sau --version, dar numai atunci când este invocat în
Forma „[”, când ultimul argument nu este „]”. Utilizați direct
parsing, mai degrabă decât parse_long_options, pentru a evita acceptarea
abrevieri. POSIX permite „[ --help” și „[ --version” să
au comportamentul obișnuit GNU, dar necesită „test --help”
și „test --version” pentru a ieși în tăcere cu starea 0. */
Publicitate

Putem vedea efectul acestui lucru solicitând ajutor test și [ și verificând codul de răspuns trimis către Bash.

 test --ajutor
 eco $?
 [ --Ajutor
 eco $? 

Folosind --help la test și [

Atât test , cât și [ sunt shell built -in , ceea ce înseamnă că sunt coapte chiar în Bash. Dar există și o versiune binară de sine stătătoare a [ .

 test de tip
 tip [
 unde este [ 

Găsirea diferitelor tipuri de [ și comenzi de testare

Prin contrast, testele condiționale cu paranteze duble [[ și ]] sunt cuvinte cheie . [[ și ]] efectuează și teste logice, dar sintaxa lor este diferită. Deoarece sunt cuvinte cheie, puteți folosi câteva funcții îngrijite care nu vor funcționa în versiunea cu o singură paranteză.

Cuvintele cheie dublu paranteză sunt acceptate de Bash, dar nu sunt disponibile în orice alt shell. De exemplu, shell-ul Korn le susține, dar shell-ul vechi simplu, sh, nu. Toate scripturile noastre încep cu linia:

 #!/bin/bash

Acest lucru asigură că apelăm shell-ul Bash pentru a rula scriptul.

LEGATE: Cum să creați și să rulați scripturi Bash Shell pe Windows 10

Construcții și cuvinte cheie

Putem folosi programul compgen pentru a lista elementele interne:

 compgen -b | fmt -w 70
Publicitate

Fără a trimite ieșirea prin fmt , am obține o listă lungă cu fiecare încorporat pe propria linie. Este mai convenabil în acest caz să vezi elementele încorporate grupate într-un paragraf.

Listarea elementelor integrate Bash

Putem vedea test și [ în listă, dar ] nu este listat. Comanda [ caută o închidere ] pentru a detecta când a ajuns la sfârșitul expresiei, dar ] nu este o unitate încorporată separată. Este doar un semnal pe care îl dăm lui [ pentru a indica sfârșitul listei de parametri.

Pentru a vedea cuvintele cheie, putem folosi:

 compgen -k | fmt -w 70 

Listarea cuvintelor cheie Bash

Cuvintele cheie [[ și ]] sunt ambele în listă, deoarece [[ este un cuvânt cheie și ]] este altul. Sunt o pereche potrivită, la fel ca if și fi , și case și esac .

Când Bash analizează un script – sau o linie de comandă – și detectează un cuvânt cheie care are un cuvânt cheie care se potrivește, de închidere, adună tot ce apare între ele și aplică orice tratament special acceptat de cuvintele cheie.

Cu o versiune încorporată, ceea ce urmează comenzii încorporate îi este transmis exact ca parametrii oricărui alt program de linie de comandă. Aceasta înseamnă că autorul scriptului trebuie să aibă o grijă deosebită în ceea ce privește lucruri precum spațiile în valorile variabile.

Shell Globbing

Testele condiționate cu paranteză dublă pot folosi shell globbing. Aceasta înseamnă că asteriscul „ * ” se va extinde pentru a însemna „orice”.

Publicitate

Tastați sau copiați următorul text într-un editor și salvați-l într-un fișier numit „whelkie.sh”.

 #!/bin/bash

stringvar="Whelkie Brookes"

if [[ "$stringvar" == *elk* ]];
atunci
  ecou „Avertismentul conține fructe de mare”
altfel
  ecou „Fără moluște”
fi

Pentru a face scriptul executabil, va trebui să folosim comanda chmod cu opțiunea -x (execute). Va trebui să faceți acest lucru pentru toate scripturile din acest articol dacă doriți să le încercați.

 chmod +x whelkie.sh 

Folosind chmod pentru a face un script executabil

Când rulăm scriptul, vedem că șirul „elk” a fost găsit în șirul „Whelkie”, indiferent de ce alte caractere îl înconjoară.

 ./whelkie.sh 

Rularea scriptului whelkie.sh

Un punct de remarcat este că nu înfășurăm șirul de căutare între ghilimele duble. Dacă o faci, globbingul nu se va întâmpla. Șirul de căutare va fi tratat literal.

Sunt permise alte forme de stropire a cochiliei. Semnul întrebării „ ? ” se va potrivi cu caractere individuale, iar parantezele pătrate simple sunt folosite pentru a indica intervalele de caractere. De exemplu, dacă nu știi ce husă să folosești, poți acoperi ambele eventualități cu o gamă.

 #!/bin/bash

stringvar="Jean-Claude van Clam"

if [[ "$stringvar" == *[cC]lam* ]];
atunci
  echo „Avertismentul conține fructe de mare”.
altfel
  ecou „Fără moluște”.
fi

Salvați acest script ca „damme.sh” și faceți-l executabil. Când o rulăm, instrucțiunea condiționată se rezolvă la adevărat și prima clauză a instrucțiunii if este executată.

 ./damme.sh 

Rularea scriptului damme.sh

Citate șiruri

Am menționat mai devreme împachetarea șirurilor de caractere între ghilimele duble. Dacă o faci, shell globbing nu va avea loc. Deși convenția spune că este o practică bună, nu trebuie să înfășurați variabilele șir între ghilimele atunci când utilizați [[ și ]] chiar dacă acestea conțin spații. Uită-te la următorul exemplu. Atât variabilele șir $stringvar și $surname conțin spații, dar nici una nu este citată în instrucțiunea condiționată.

 #!/bin/bash

stringvar="van Damme"
surname="van Damme"

if [[ $stringvar == $prenume ]];
atunci
echo „Numele de familie se potrivesc”.
altfel
echo „Numele de familie nu se potrivesc”.
fi
Publicitate

Salvați acest lucru într-un fișier numit „surname.sh” și faceți-l executabil. Rulați-l folosind:

 ./nume.sh 

Rularea scriptului surname.sh

În ciuda ambelor șiruri de caractere care conțin spații, scriptul reușește și instrucțiunea condiționată se rezolvă la adevărat. Acest lucru este util atunci când aveți de-a face cu căi și nume de directoare care conțin spații. Aici, opțiunea -d returnează adevărat dacă variabila conține un nume de director valid.

 #!/bin/bash

dir="/home/dave/Documents/Needs Work"

dacă [[ -d ${dir} ]];
atunci
  echo „Director confirmat”
altfel
  echo „Directorul nu a fost găsit”
fi

Dacă modificați calea în script pentru a reflecta un director pe propriul computer, salvați textul într-un fișier numit „dir.sh” și îl faceți executabil, puteți vedea că acest lucru funcționează.

 ./dir.sh 

Rularea scriptului dir.sh

LEGATE: Cum să lucrați cu variabile în Bash

Nume fișier Globbing Gotchas

O diferență interesantă între [ ] și [[ ]] se referă la numele fișierelor cu globbing în ele. Forma „*.sh” se va potrivi cu toate fișierele script. Utilizarea parantezelor simple [ ] nu reușește, cu excepția cazului în care există un singur fișier script. Găsirea mai multor scripturi generează o eroare.

Iată scriptul cu condiționale cu o singură paranteză.

 #!/bin/bash

dacă [ -a *.sh ];
atunci
  echo „Am găsit un fișier script”
altfel
  echo „Nu am găsit un fișier script”
fi

Am salvat acest text în „script.sh” și l-am făcut executabil. Am verificat câte scripturi erau în director, apoi am rulat scriptul.

 ls
 ./script.sh 

Rularea scriptului script.sh

Publicitate

Bash aruncă o eroare. Am eliminat toate fișierele script cu excepția unuia și am rulat din nou scriptul.

 ls
 ./script.sh 

Rularea scriptului script.sh cu un singur script în director

Testul condiționat returnează adevărat și scriptul nu provoacă o eroare. Editarea scriptului pentru a utiliza paranteze duble oferă un al treilea tip de comportament.

 #!/bin/bash

dacă [[ -a *.sh ]];
atunci
  echo „Am găsit un fișier script”
altfel
  echo „Nu am găsit un fișier script”
fi

Am salvat acest lucru într-un fișier numit „dscript.sh” și l-am făcut executabil. Rularea acestui script într-un director cu multe scripturi în el nu generează o eroare, dar scriptul nu recunoaște niciun fișier de script.

Declarația condiționată care folosește paranteze duble se rezolvă la adevărat numai în cazul improbabil în care aveți un fișier numit de fapt „*.sh” în director.

 ./dscript.sh 

Rularea scriptului dscript.sh

ȘI și SAU logic

Parantezele duble vă permit să utilizați && și || ca operatori logici AND și SAU.

Acest script ar trebui să rezolve declarația condiționată la adevărat, deoarece 10 este egal cu 10 și 25 este mai mic decât 26.

 #!/bin/bash

primul=10
secunda=25

dacă [[ primul -eq 10 && al doilea -lt 26 ]];
atunci
  ecou „Condiția îndeplinită”
altfel
  echo „Condiția a eșuat”
fi
Publicitate

Salvați acest text într-un fișier numit „and.sh”, faceți-l executabil și rulați-l cu:

 ./și.sh 

Rularea scriptului and.sh

Scriptul se execută așa cum ne-am aștepta.

De data aceasta vom folosi || operator. Propoziția condiționată ar trebui să se rezolve la adevărat deoarece, deși 10 nu este mai mare decât 15, 25 este totuși mai mic decât 26. Atâta timp cât fie prima comparație, fie a doua comparație este adevărată, declarația condiționată în ansamblu se rezolvă la adevărat.

Salvați acest text ca „or.sh” și faceți-l executabil.

 #!/bin/bash

primul=10
secunda=25

dacă [[ primul -gt 15 || al doilea -lt 26 ]];
atunci
  echo „Condiția îndeplinită”.
altfel
  echo „Condiția a eșuat”.
fi
 ./sau.sh 

Rularea scriptului or.sh

Regexe

Instrucțiunile condiționate cu paranteze duble permit utilizarea operatorului =~ , care aplică modelele de căutare regex dintr-un șir în cealaltă jumătate a instrucțiunii. Dacă regex este satisfăcută, declarația condiționată este considerată adevărată. Dacă regex nu găsește nicio potrivire, declarația condiționată se rezolvă la false.

LEGATE: Cum să utilizați expresiile regulate (regexes) pe Linux

Salvați acest text într-un fișier numit „regex.sh” și faceți-l executabil.

 #!/bin/bash

cuvinte = "unu doi trei"
WordsandNumbers="unu 1 doi 2 trei 3"
email="[email protected]"

mask1="[0-9]"
mask2="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}"

if [[ $cuvinte =~ $mask1 ]];
atunci
  echo "\"$cuvinte\" conține cifre."
altfel
  echo "Nu s-au găsit cifre în \"$words\"."
fi

dacă [[ $WordsandNumbers =~ $mask1 ]];
atunci
  echo "\"$WordsandNumbers\" conține cifre."
altfel
  echo "Nu s-au găsit cifre în \"$WordsandNumbers\"."
fi

if [[ $email =~ $mask2 ]];
atunci
  echo "\"$email\" este o adresă de e-mail validă."
altfel
  echo "Nu s-a putut analiza \"$email\"."
fi

Primul set de paranteze duble folosește variabila șir $mask1 ca regex. Acesta conține modelul pentru toate cifrele din intervalul de la zero la nouă. Se aplică această regex variabilei șir $words .

Al doilea set de paranteze duble folosește din nou variabila șir $mask1 ca regex, dar de data aceasta o folosește cu variabila șir $WordsandNumbers .

Publicitate

Ultimul set de paranteze duble folosește o mască regex mai complexă în variabila șir $mask2 .

  • [A-Za-z0-9._%+-]+ : se potrivește oricărui caracter care este o literă mare sau minusculă, sau orice cifră de la zero la nouă, sau un punct, liniuță de subliniere, semn procentual sau semn plus sau minus . „ + ” din afara „ [] ” înseamnă că se repetă acele potriviri pentru câte caractere găsește.
  • @ : Aceasta se potrivește numai cu caracterul „@”.
  • [A-Za-z0-9.-]+ : Se potrivește oricărui caracter care este o literă mare sau minusculă, sau orice cifră de la zero la nouă, sau un punct sau o cratimă. „ + ” din afara „ [ ] ” înseamnă că repeta acele potriviri pentru câte caractere găsește.
  • . : Aceasta se potrivește cu „.” numai caracterul.
  • [A-Za-z]{2,4} : aceasta se potrivește cu orice literă mare sau minusculă. „ {2,4} ” înseamnă potrivire cu cel puțin două caractere și cel mult patru.

Punând toate acestea împreună, masca regex va verifica dacă o adresă de e-mail este formată corect.

Salvați textul scriptului într-un fișier numit „regex.sh” și faceți-l executabil. Când rulăm scriptul, obținem această ieșire.

 ./regex.sh 

Rularea scriptului regex.sh

Prima instrucțiune condiționată eșuează deoarece regex-ul caută cifre, dar nu există cifre în valoarea deținută în variabila șir $words .

A doua instrucțiune condiționată reușește deoarece variabila șir $WordsandNumbers conține cifre.

Publicitate

Declarația condițională finală reușește - adică se rezolvă la adevărat - deoarece adresa de e-mail este formatată corect.

O singură condiție

Testele condiționate cu paranteze duble aduc flexibilitate și lizibilitate scripturilor dvs. Doar faptul că poți folosi regexe în testele tale condiționate justifică învățarea cum să folosești [[ și ]] .

Doar asigurați-vă că scriptul apelează un shell care le acceptă, cum ar fi Bash.

RELATE: 15 personaje speciale pe care trebuie să le cunoașteți pentru Bash