Cum să utilizați getopts pentru a analiza opțiunile de script Linux Shell
Publicat: 2022-06-25 Doriți ca scripturile dvs. Linux shell să gestioneze opțiunile și argumentele din linia de comandă mai grațios? Sistemul integrat Bash getopts
vă permite să analizați opțiunile din linia de comandă cu finețe – și este, de asemenea, ușor. Vă arătăm cum.
Vă prezentăm sistemul încorporat getopts
Transmiterea de valori într-un script Bash este o chestiune destul de simplă. Vă apelați scriptul din linia de comandă sau dintr-un alt script și furnizați lista de valori în spatele numelui scriptului. Aceste valori pot fi accesate în interiorul scriptului ca variabile, începând cu $1
pentru prima variabilă, $2
pentru a doua și așa mai departe.
Dar dacă vrei să treci opțiuni unui script, situația devine rapid mai complexă. Când spunem opțiuni, ne referim la opțiunile, steagurile sau comutatoarele pe care programe precum ls
le pot gestiona. Sunt precedate de o liniuță „ -
” și de obicei acționează ca un indicator al programului pentru a activa sau dezactiva un anumit aspect al funcționalității acestuia.
Comanda ls
are peste 50 de opțiuni, legate în principal de formatarea ieșirii sale. Opțiunea -X
(sortează după extensie) sortează rezultatul alfabetic după extensia fișierului. Opțiunea -U
(nesortată) listează în ordinea directorului.
Opțiunile sunt doar atât - sunt opționale. Nu știți ce opțiuni – dacă există – va alege utilizatorul să folosească și nici nu știți în ce ordine le poate enumera pe linia de comandă. Acest lucru crește complexitatea codului necesar pentru a analiza opțiunile.
Lucrurile devin și mai complicate dacă unele dintre opțiunile dvs. iau un argument, cunoscut sub numele de argument opțiune . De exemplu, opțiunea ls -w
(lățime) se așteaptă să fie urmată de un număr, reprezentând lățimea maximă de afișare a ieșirii. Și, desigur, s-ar putea să treci în scriptul tău alți parametri care sunt pur și simplu valori de date, care nu sunt deloc opțiuni.
Din fericire, getopts
se ocupă de această complexitate pentru tine. Și pentru că este încorporat, este disponibil pe toate sistemele care au shell-ul Bash, așa că nu este nimic de instalat.
Notă: getopts Nu getopt
Există un utilitar mai vechi numit getopt
. Acesta este un mic program utilitar, nu un program încorporat. Există multe versiuni diferite de getopt
cu comportamente diferite, în timp ce getops
încorporat urmează liniile directoare POSIX.
tip getopts
tip getopt
Deoarece getopt
nu este o versiune încorporată, nu împărtășește unele dintre beneficiile automate pe care le are getopts
, cum ar fi gestionarea rațională a spațiilor albe. Cu getopts
, shell-ul Bash rulează scriptul și shell-ul Bash face analiza opțiunii. Nu trebuie să invocați un program extern pentru a gestiona analiza.
Compensația este că getopts
nu tratează nume de opțiuni cu liniuțe duble și format lung. Deci, puteți utiliza opțiuni formatate ca -w
, dar nu „ ---wide-format
”. Pe de altă parte, dacă aveți un script care acceptă opțiunile -a
, -b
și
, -c
getopts
vă permite să le combinați ca -abc
, -bca
, sau -bac
și așa mai departe.
Discutăm și demonstrăm getopts
în acest articol, așa că asigurați-vă că adăugați „s” final la numele comenzii.
LEGATE: Cum să evadați din spațiile din căile fișierelor de pe linia de comandă Windows
O recapitulare rapidă: gestionarea valorilor parametrilor
Acest script nu folosește opțiuni întrerupte precum -a
sau -b
. Acceptă parametri „normali” pe linia de comandă și aceștia sunt accesați în interiorul scriptului ca valori.
#!/bin/bash # obțineți variabilele una câte una echo „Variabila unu: $1” echo „Variabila 2: $2” echo „Variabila trei: $3” # buclă prin variabile pentru var în „ $@” do ecou „$ var” Terminat
Parametrii sunt accesați în interiorul scriptului ca variabile $1
, $2
sau $3
.
Copiați acest text într-un editor și salvați-l ca fișier numit „variables.sh”. Va trebui să îl facem executabil cu comanda chmod
. Va trebui să faceți acest pas pentru toate scripturile pe care le discutăm. Doar înlocuiți numele fișierului script corespunzător de fiecare dată.
chmod +x variabile.sh
Dacă rulăm scriptul nostru fără parametri, obținem această ieșire.
./variabile.sh
Nu am trecut niciun parametri, așa că scriptul nu are valori de raportat. Să oferim de data aceasta câțiva parametri.
./variables.sh cum să faci toci
După cum era de așteptat, variabilele $1
, $2
și $3
au fost setate la valorile parametrilor și le vedem tipărite.
Acest tip de manipulare a parametrilor unu-la-unu înseamnă că trebuie să știm dinainte câți parametri vor exista. Buclei din partea de jos a scriptului nu-i pasă de câți parametri există, îi trece întotdeauna în buclă pe toți.
Dacă oferim un al patrulea parametru, acesta nu este atribuit unei variabile, dar bucla îl gestionează în continuare.
./variables.sh cum să faci site-ul tocilar
Dacă punem ghilimele în jurul a două dintre cuvinte, acestea sunt tratate ca un parametru.
./variables.sh cum „să faci tocilar”
Dacă vom avea nevoie de scriptul nostru pentru a gestiona toate combinațiile de opțiuni, opțiuni cu argumente și parametrii de tip de date „normali”, va trebui să separăm opțiunile de parametrii obișnuiți. Putem realiza acest lucru plasând toate opțiunile - cu sau fără argumente - înaintea parametrilor obișnuiți.
Dar să nu alergăm înainte să putem merge. Să ne uităm la cel mai simplu caz pentru gestionarea opțiunilor din linia de comandă.
Opțiuni de manipulare
Folosim getopts
într-o buclă while
. Fiecare iterație a buclei funcționează pe o opțiune care a fost transmisă scriptului. În fiecare caz, variabila OPTION
este setată la opțiunea identificată de getopts
.
Cu fiecare iterație a buclei, getopts
trece la următoarea opțiune. Când nu mai există opțiuni, getopts
returnează false
și bucla while
iese.
Variabila OPTION
este comparată cu modelele din fiecare dintre clauzele declarației case. Deoarece folosim o declarație case, nu contează în ce ordine sunt furnizate opțiunile pe linia de comandă. Fiecare opțiune este introdusă în declarația case și este declanșată clauza corespunzătoare.
Clauzele individuale din instrucțiunea case facilitează efectuarea de acțiuni specifice opțiunii în cadrul scriptului. De obicei, într-un script din lumea reală, ați seta o variabilă în fiecare clauză, iar acestea ar acționa ca indicatori mai departe în script, permițând sau interzicând anumite funcționalități.
Copiați acest text într-un editor și salvați-l ca un script numit „options.sh” și faceți-l executabil.
#!/bin/bash while getopts 'abc' OPTIUNEA; do cazul „$OPTION” în A) echo "Opțiune a folosită" ;; b) echo „Opțiunea b folosită” ;; c) echo „Opțiunea c folosită” ;; ?) echo „Utilizare: $(nume de bază $0) [-a] [-b] [-c]” iesirea 1 ;; esac Terminat
Aceasta este linia care definește bucla while.
while getopts 'abc' OPTIUNEA; do
Comanda getopts
este urmată de șirul de opțiuni . Aceasta listează literele pe care le vom folosi ca opțiuni. Doar literele din această listă pot fi folosite ca opțiuni. Deci, în acest caz, -d
ar fi invalid. Acest lucru ar fi prins de clauza ?)
, deoarece getopts
returnează un semn de întrebare „ ?
” pentru o opțiune neidentificată. Dacă se întâmplă acest lucru, utilizarea corectă este tipărită în fereastra terminalului:
echo „Utilizare: $(nume de bază $0) [-a] [-b] [-c]”
Prin convenție, includerea unei opțiuni între paranteze „ []
” în acest tip de mesaj de utilizare corectă înseamnă că opțiunea este opțională. Comanda basename elimină toate căile de director din numele fișierului. Numele fișierului script este păstrat în $0
în scripturile Bash.
Să folosim acest script cu diferite combinații de linie de comandă.
./opțiuni.sh -a
./opțiuni.sh -a -b -c
./options.sh -ab -c
./opțiuni.sh -cab
După cum putem vedea, toate combinațiile noastre de testare de opțiuni sunt analizate și gestionate corect. Ce se întâmplă dacă încercăm o opțiune care nu există?
./opțiuni.sh -d
Clauza de utilizare este declanșată, ceea ce este bine, dar primim și un mesaj de eroare din shell. Acest lucru ar putea sau nu conta pentru cazul dvs. de utilizare. Dacă apelați scriptul dintr-un alt script care trebuie să analizeze mesaje de eroare, va fi mai dificil dacă și shell-ul generează mesaje de eroare.
Oprirea mesajelor de eroare shell este foarte ușoară. Tot ce trebuie să facem este să punem două puncte ” :
” ca primul caracter al șirului de opțiuni.
Fie editați fișierul „options.sh” și adăugați două puncte ca prim caracter al șirului de opțiuni, fie salvați acest script ca „options2.sh” și faceți-l executabil.
#!/bin/bash while getopts ':abc' OPTIUNEA; do cazul „$OPTION” în A) echo „Opțiune a folosită” ;; b) echo „Opțiunea b folosită” ;; c) echo „Opțiunea c folosită” ;; ?) echo „Utilizare: $(nume de bază $0) [-a] [-b] [-c]” iesirea 1 ;; esac Terminat
Când rulăm acest lucru și generăm o eroare, primim propriile noastre mesaje de eroare fără mesaje shell.
./options2.sh.sh -d
Utilizarea getopts cu argumente opțiuni
Pentru a spune getopts
că o opțiune va fi urmată de un argument, puneți două puncte ” :
” imediat după litera opțiunii din șirul de opțiuni.
Dacă urmăm „b” și „c” din șirul nostru de opțiuni cu două puncte, getopt
se va aștepta la argumente pentru aceste opțiuni. Copiați acest script în editor și salvați-l ca „arguments.sh” și faceți-l executabil.
Amintiți-vă, primele două puncte din șirul de opțiuni sunt folosite pentru a suprima mesajele de eroare shell - nu are nimic de-a face cu procesarea argumentelor.
Când getopt
procesează o opțiune cu un argument, argumentul este plasat în variabila OPTARG
. Dacă doriți să utilizați această valoare în altă parte a scriptului dvs., va trebui să o copiați într-o altă variabilă.
#!/bin/bash while getopts ':ab:c:' OPȚIUNE; do cazul „$OPTION” în A) echo „Opțiune a folosită” ;; b) argB="$OPTARG" echo „Opțiunea b folosită cu: $argB” ;; c) argC="$OPTARG" echo „Opțiunea c folosită cu: $argC” ;; ?) echo "Utilizare: $(nume de bază $0) [-a] [-b argument] [-c argument]" iesirea 1 ;; esac Terminat
Să rulăm asta și să vedem cum funcționează.
./arguments.sh -a -b „cum să faci toci” -c reviewgeek
./arguments.sh -c reviewgeek -a
Deci acum putem gestiona opțiunile cu sau fără argumente, indiferent de ordinea în care sunt date pe linia de comandă.
Dar cum rămâne cu parametrii obișnuiți? Am spus mai devreme că știm că va trebui să le punem pe linia de comandă după orice opțiune. Să vedem ce se întâmplă dacă o facem.
Opțiuni de amestecare și parametri
Vom schimba scriptul nostru anterior pentru a include încă o linie. Când bucla while
a ieșit și toate opțiunile au fost gestionate, vom încerca să accesăm parametrii obișnuiți. Vom imprima valoarea în $1
.
Salvați acest script ca „arguments2.sh” și faceți-l executabil.
#!/bin/bash while getopts ':ab:c:' OPȚIUNE; do cazul „$OPTION” în A) echo „Opțiune a folosită” ;; b) argB="$OPTARG" echo „Opțiunea b folosită cu: $argB” ;; c) argC="$OPTARG" echo „Opțiunea c folosită cu: $argC” ;; ?) echo "Utilizare: $(nume de bază $0) [-a] [-b argument] [-c argument]" iesirea 1 ;; esac Terminat echo „Variabila una este: $1”
Acum vom încerca câteva combinații de opțiuni și parametri.
./arguments2.sh dave
./arguments2.sh -a dave
./arguments2.sh -a -c how-to-geek dave
Deci acum putem vedea problema. De îndată ce orice opțiune este utilizată, variabilele $1
în continuare sunt completate cu steagurile opțiunii și argumentele acestora. În ultimul exemplu, $4
ar deține valoarea parametrului „dave”, dar cum o accesați în scriptul dumneavoastră dacă nu știți câte opțiuni și argumente vor fi folosite?
Răspunsul este să utilizați OPTIND
și comanda shift
.
Comanda shift
elimină primul parametru, indiferent de tip, din lista de parametri. Ceilalți parametri „se amestecă în jos”, astfel încât parametrul 2 devine parametrul 1, parametrul 3 devine parametrul 2 și așa mai departe. Și astfel $2
devine $1
, $3
devine $2
și așa mai departe.
Dacă oferiți shift
cu un număr, va elimina atât de mulți parametri din listă.
OPTIND
numără opțiunile și argumentele pe măsură ce sunt găsite și procesate. Odată ce toate opțiunile și argumentele au fost procesate, OPTIND
va fi cu unul mai mare decât numărul de opțiuni. Deci, dacă folosim shift pentru a tăia (OPTIND-1)
parametrii din lista de parametri, vom rămâne cu parametrii obișnuiți din $1
în continuare.
Exact asta face acest script. Salvați acest script ca „arguments3.sh” și faceți-l executabil.
#!/bin/bash while getopts ':ab:c:' OPȚIUNE; do cazul „$OPTION” în A) echo „Opțiune a folosită” ;; b) argB="$OPTARG" echo „Opțiunea b folosită cu: $argB” ;; c) argC="$OPTARG" echo „Opțiunea c folosită cu: $argC” ;; ?) echo "Utilizare: $(nume de bază $0) [-a] [-b argument] [-c argument]" iesirea 1 ;; esac Terminat echo „Înainte - variabila una este: $1” shift „$(($OPTIND -1))” echo „După - variabila unu este: $1” echo „Restul argumentelor (operanzilor)” pentru x în „$@” do eco $x Terminat
Vom rula acest lucru cu un amestec de opțiuni, argumente și parametri.
./arguments3.sh -a -c „Dave Dee” mick tich
Putem vedea că înainte de a numi shift
, $1
ținea „-a”, dar după comanda shift $1
deține primul nostru parametru non-opțiune, non-argument. Putem parcurge toți parametrii la fel de ușor ca într-un script fără opțiune de analizare.
Întotdeauna este bine să ai opțiuni
Gestionarea opțiunilor și a argumentelor acestora în scripturi nu trebuie să fie complicată. Cu getopts
puteți crea scripturi care gestionează opțiunile, argumentele și parametrii din linia de comandă exact așa cum ar trebui scripturile native compatibile cu POSIX.