0. Index
- Lucruri care se întâmplă majorității oamenilor
- Structura unui scenariu
- Imprimați pe ecran
- Citiți INPUT-ul utilizatorului
- Calcule în bash
- Termeni
- Bucle
- funcţii
- getops
1. Lucruri care se întâmplă majorității oamenilor
/ bin / bash sau / bin / sh
Unul dintre primele lucruri pe care le face mașina atunci când execută scriptul nostru este căutarea cu care shell ar trebui să o facă. Pe majoritatea sistemelor Linux actuale / Bin / sh este un link către / bin / bash, dar acest lucru nu este întotdeauna cazul, de exemplu în distribuțiile care utilizează Busybox aduce Sh și de obicei aduc și ele Bash, dar dacă folosești / Bin / sh, nu va rula cu Bash. De aceea recomand să folosiți întotdeauna / bin / bash.
Unicode vs. ASCII
Te-ai întrebat vreodată de ce nu poți folosi „¿” sau „ñ” în scripturile tale? Sau folosiți accente? Poate fi destul de enervant în scripturile interactive. Asta pentru că codificarea implicită pentru Bash este ASCII, sau ceea ce este același, setul de caractere englezesc. Pentru a-l schimba, trebuie doar să-i spunem scriptului că dorim să folosim Unicode. Pentru aceasta trebuie să adăugați o linie imediat după interpretul de comandă:
# - * - CODIFICARE: UTF-8 - * -
Aveți grijă, este important ca această linie să fie la începutul scenariului.
Faceți scriptul executabil
Este amuzant câți oameni rulează scripturile cu «$ bashscript.sh" in loc de "$ ./script.sh„La urma urmei, pentru asta am definit un shell.
Pentru a adăuga permisiuni de execuție, trebuie să executați:
sudo + x script.sh
BIN = "folder unde avem scripturile" PATH = "$ BIN $ PATH"
2. Structura unui script
- Cap
- Definiția variabilelor globale
- Ajutor
- funcţii
- Corpul principal
Antetul este locul în care indicăm ce shell dorim să folosim și codificarea. Avantajul funcțiilor este reutilizarea codului care se repetă scriindu-l o singură dată și pentru a ușura înțelegerea scriptului, pentru codul care depășește 100 de linii este foarte util.
Pentru a utiliza funcțiile, acestea trebuie definite în fața corpului principal al scriptului nostru. Și dacă dorim să utilizăm variabile la nivel global al tuturor scripturilor noastre, atât în corpul principal, cât și în funcții, trebuie să le definim la începutul tuturor, imediat după antet.
În cele din urmă, este o bună practică să scriem o funcție de ajutor pentru atunci când scriptul nostru rulează prost sau cu parametri deficienți. Evident, în aceste cazuri dorim să ieșim din script imediat, fără a citi funcțiile. Pentru aceasta putem folosi:
function help () {echo "" "Textul nostru de ajutor bine formatat." "" Ieșiți dacă [[-z $ 1 || $ 1 == "-h" || $ 1 == "--help"]]; apoi ajuta fi
Dacă adăugăm „exit” la funcția de ajutor, vom ieși din script de fiecare dată când rulăm ajutor, de exemplu după mesaje de eroare etc. Salvăm câteva linii de cod.
Condiția indică ajutorul pentru afișare pe ecran și iese dacă scriptul este rulat fără parametri sau dacă este specificat -h / –help. Dacă te uiți la el, acesta este comportamentul standard al majorității programelor Linux.
3. Imprimați pe ecran
Există 2 comenzi principale pentru imprimarea pe ecran în bash: «ecou»Y«printf«. Ambele sunt la fel de rapide și ambele fac parte din bash. Principala diferență pentru un începător este că ecoul adaugă o linie nouă la sfârșit, în timp ce «printf"Nu.
Ecoul este foarte bun și este ceea ce utilizează majoritatea oamenilor, cu toate acestea atunci când citesc INPUT-ul utilizatorului sau când doriți să imprimați variabile preluate din fișiere prin procesarea textului, se pot întâmpla lucruri ciudate. De obicei, acestea se rezolvă ușor, la fel de ușor ca schimbarea ghilimelelor duble la simple sau invers sau scoaterea din ghilimele a referințelor variabile. «Ecou»Face lucruri ciudate, de asemenea, în funcție de modul în care a fost compilat, dacă folosim întotdeauna Ubuntu sau întotdeauna Fedora, nu ne afectează, dar dacă schimbăm distribuția, nu.
De aceea folosesc «printf«, Ceea ce nu-mi dă dureri de cap și se comportă mai mult ca«printf»Din C sau«imprima»Din Python, acest lucru este foarte important dacă vreți vreodată să vă transferați scriptul într-un alt limbaj de programare.
4. Citiți INPUT-ul utilizatorului
Tot ceea ce scriem după numele scriptului nostru și înainte de a apăsa tasta ENTER este salvat automat în variabile speciale. Aceste variabile sunt de tipul $ X unde X este un număr.
«$0»Indică numele scriptului nostru și din«$1»Pentru infinit tot ceea ce am scris mai târziu este variabil. De exemplu:
cat << EOF >> test.sh #! / bin / bash # - * - CODIFICARE: UTF-8 - * - printf "\ $ 0 = $ 0 \ n" printf "\ $ 1 = $ 1 \ n" printf "\ $ 2 = $ 2 \ n "EOF chmod + x script.sh ./script.sh my file.txt
Creăm un script de testare, îl facem executabil și îl rulăm cu 2 parametri. Obținem ieșirea pe ecran a:
$ 0 = ./script.sh $ 1 = $ 2 meu = file.txt
Folosind ghilimele am fi putut trece „fișierul meu.txt” la „$ 1”.
De asemenea, putem citi INPUT-ul unui utilizator cu comanda „read”, indicând direct variabila unde dorim să salvăm parametrul. De exemplu:
printf "Care este numele tău? \ n" citește NAME printf "Bună ziua, $ NAME. \ n"
5. Calcule în Bash
Pentru asta putem folosi «expres«Atâta timp cât nu este nevoie să facem calcule complexe. Trebuie menționate două lucruri, primul este că «expres»Admite doar numere întregi, a doua este că diviziunea returnează întregul rezultat, pentru a vedea restul putem folosi«%“.
De obicei, vrem să atribuim rezultatul expr unei variabile. Putem face acest lucru în două moduri:
VAR2 = `expr $ VAR1 / 10` VAR2 = $ (expr $ VAR1 / 100)
De asemenea, puteți sări peste «expres»Utilizarea parantezelor duble:
VAR2 = $ (($ VAR1 / 100))
6. termeni
A fost deja scris într-un mod foarte extins despre «if""altfel""Elif»Și condiții. Puteți citi despre asta în:
- Programare în bash: partea 1
- Bash: dacă, atunci, altfel condiții
- Verificați dacă există sau nu un fișier sau folder și mai multe cu o buclă if
- Programare în bash: partea 2
Vreau doar să evidențiez diferența dintre utilizarea parantezelor pătrate simple, «[]«, Și paranteze duble,«[[]]«, Pentru condiții. Cu paranteze duble putem folosi condiții suplimentare:
- «&&»Pentru și
- «||»Pentru sau
A folosi "&&»Y«||»Cu paranteze pătrate simple, fiecare parte trebuie separată în paranteze pătrate separate. Exemplul folosit pentru partea din script care arată dacă trebuie executat ajutorul ar fi:
dacă [-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "--help"]]; apoi ajuta fi
De asemenea, ne scutește să scriem nume de variabile între ghilimele pentru a preveni erorile. De exemplu:
dacă [$ 1 = 1]; apoi printf "Parametrul este egal cu 1."; fi if ["$ 1" = 1]; apoi printf "Parametrul este egal cu 1."; fi if [[$ 1 = 1]]; apoi printf "Parametrul este egal cu 1."; fi
Dacă script.sh este rulat fără parametri, primul caz ar da o eroare:
bash: [: =: operator unar așteptat
Despre ce nu s-a vorbit este «caz«, Folosit pentru simplificare«if«. Să începem de la început, când nu avem niciunul «if»Tot codul va fi executat. Dacă adăugăm o condiție «if»Vom avea două cazuri, unul în care blocul de cod care se află în interiorul«if»Și celălalt caz în care acest bloc nu este executat.
Dacă adăugăm un «altfel«Vom avea și două cazuri, dar aceste două cazuri sunt diferite de cele anterioare. Pentru că acum vor exista două blocuri de cod condiționate, A și B, și un bloc C, care este restul programului. A sau B vor fi executate, iar C. În cazul anterior, era A și C sau numai C.
Pentru a evita condițiile de scriere «dacă / altfel" în "altfel»Și pentru a simplifica citirea codului, acesta a fost creat«Elif«. Când avem multe condiții care depind de cea anterioară, de exemplu gama de numere sau tipul:
VAR1 = $ 1 dacă [[$ VAR1 = 1]]; apoi printf "1 \ n" elif [[$ VAR1 = 2]]; apoi printf "2 \ n" elif [[$ VAR1 = 3]]; apoi printf "3 \ n" altfel printf "none \ n" fi
În cazul ultimului «Elif»Se vor citi multe condiții. În cazul în care acest proces este simplificat:
VAR1 = $ 1 carcasă $ VAR în 1) printf "1 \ n" ;; 2) printf "2 \ n" ;; 3 | 4) printf "3 sau 4, depinde \ n" ;; *) printf "none \ n" ;; că C
Se va citi o variabilă, în acest caz VAR1, și se va verifica dacă este echivalentă cu oricare dintre cazuri, dacă nu, se va executa cazul implicit „*”. Punctele și virgulele duble sunt echivalente cu «rupe", Ei spun"caz»Asta trebuie să se termine.
7. Bucle
Foarte puține bucle sunt cunoscute în orice limbaj de programare. În Bash sunt «în timp ce""până la»Y«pentru«. A fost deja scris în blog despre acestea:
Există două tipuri de bucle «pentru«, Cei care sunt de tipul«$ pentru VAR în LOQUESEA»Și ce sunt de tip C«$ pentru ((I = 0; I <= 10; I ++))«. Al doilea tip de bucle «pentru»Sunt foarte utile, are 3 părți la începutul buclei:
- Declarația și inițierea variabilelor (În acest caz, o variabilă auxiliară "I = 0").
- Condiția de execuție (până când I este mai mic sau egal cu 10).
- Creșterea variabilei auxiliare
După părerea mea, este cea mai puternică buclă dintre toate. Un exemplu, care tipărește toate numerele de la 0 la 10, inclusiv:
#! / bin / bash for ((I = 0; I <= 10; I ++)); faceți printf "$ I \ n" gata
8. Funcții
Există câteva lucruri pe care Bash nu ne permite să le facem, nu? La prima vedere, funcțiile bash vă împiedică să faceți 3 lucruri: declararea variabilelor locale în funcții, trecerea parametrilor la funcții și returnarea parametrilor. Totul are o soluție.
Nu faceți nimic de genul:
#! / bin / bash VAR = 1 printc "$ VAR \ n" funcție salut () {VAR = 2 printf "$ VAR \ n"} salut printf "$ VAR \ n"
Aceasta se imprimă pe ecranul 1, 2 și 2.
Pentru a declara variabile locale, adăugați «local»La declararea:
#! / bin / bash VAR = 1 printf "$ VAR1 \ n" funcția foo () {local VAR1 = 2 printf "$ VAR1 \ n"} printf "$ VAR1 \ n" foo printf "$ VAR1 \ n"
Aceasta imprimă 1, 1, 2, 1 pe ecran.
Cum treceți parametrii unei funcții?
#! / bin / bash # - * - CODARE: UTF-8 - * - funcție hello () {printf "Hello $ 1 \ n"}
printf "Care este numele tău? \ n"
citiți VAR1
buna $ VAR1
Cum se returnează parametrii?
#! / bin / bash # - * - CODARE: UTF-8 - * - funcție hello () {printf "Hello holita"} printf "Care este numele tău? \ n" citește VAR1 VAR1 = $ (hello) # AICI ESTE printf "$ VAR1 $ VAR2 \ n"
După cum puteți vedea, acest lucru are două dezavantaje, puteți returna un singur parametru, care poate fi un vector 😀, iar dacă doriți să returnați un parametru, nu mai puteți imprima pe ecran din acea funcție.
9. Getops
Unul dintre ultimele lucruri pe care trebuie să le știți despre Bash pentru a crea scripturi complexe este «getops«. Este folosit pentru a transmite opțiuni scriptului indiferent de ordine. Singurul dezavantaj este că afectează doar opțiunile scurte:
#! / bin / bash # - * - CODARE: UTF-8 - * - VARC = 0 funcție help () {printf "Mesaj de ajutor \ n" exit} dacă [[-z $ 1]]; apoi ajuta fi în timp ce getopts: ha: b: c OPT; faceți cazul $ OPT în h) ajutor ;; :) Ajutor ;; a) VARA = $ OPTARG ;; b) VARB = $ OPTARG ;; c) VARC = 1 ;; \?) Ajutor ;; esac done # Blocul principal de scripturi care # face lucruri cu VARA, VARB și VARC
«getopts»Citește opțiunile una câte una, deci este necesară o buclă.
Există 2 tipuri de opțiuni care pot fi transmise folosind «getopts„:
- Parametrii numiți steaguri, în acest caz -c sau -h. Sunt specificate cu litera pe care dorim să o folosim. Sunt ca variabile booleene, «adevărat»(Are) sau«fals"(Nu sunt aici).
- Parametri cu argumente asociate, -a orice, -b orice. Sunt specificate cu litera pe care o dorim cu două puncte mai jos. Argumentul este stocat în OPTARG (acest nume este neschimbat).
Ce face acest script?
Afișează mesajul de ajutor când nu este trecută nicio opțiune, când este trecut parametrul „-h”, când este trecut un parametru nevalid (de exemplu „-x”, acest lucru se face prin „\?”) Sau când parametru valid fără argument (":"). În restul cazurilor, salvează prezența "-c" ca 1 în VARC, iar valorile trecute cu "-a" și "-b" în VARA și VARB.
MASTERAL. Nu spun mai mult U_U
Buna articol foarte bun.
Hei, ai pus să dai permisiuni sudo + x în loc de chmod + x
$ sudo chmod + x script.sh
(Pentru a fi mai exact, hehe)
Ah, felicitări și mulțumesc!
Foarte bună postare, chiar vă felicit, țineți-o așa, Salutări
Și dacă doriți ca scriptul să fie vizibil când este executat, pas cu pas, văzând de exemplu cum se comportă variabilele, condițiile și totul, puteți utiliza:
script sh -x
În ceea ce priveşte
PIEȚĂ de tutelă. Excelent și foarte bine explicat.
Mulţumesc.
Post excelent pe tema 😉
Foarte interesant și foarte important mulțumesc pentru informații….
NOROC !!!
Vă mulțumesc tuturor pentru felicitări, deoarece pentru comanda Miguel, el nu mă lasă să modific intrarea după publicare. Va trebui să facă elav îmi imaginez.
Foarte bine!
În primul rând am vrut să vă felicit pentru postare, mi s-a părut ușor de înțeles și chiar ajută să urmați liniile directoare pentru a programa bine în bash, în special pentru persoanele care încep să programeze.
Cu toate acestea, am găsit câteva detalii care cred că ar trebui corectate.
Primul: în secțiunea «2. STRUCTURA UNUI SCRIPT »funcția nu este închisă, ceea ce va cauza probleme la executarea acesteia într-un script.
Soluția ar fi adăugarea unui dispozitiv de închidere imediat după comanda „exit”.
Al doilea: în secțiunea «4. CITIȚI INTRAREA UTILIZATORULUI ”afirmați că parametrii pe care utilizatorul îi poate introduce variază de la $ 0 la infinit, cu toate acestea,„ bash ”va interpreta doar de la $ 0 la $ 9, deoarece $ 10 ar fi egal cu $ 1 + 0.
Pentru a rezolva această problemă, puteți folosi comanda „shift” pentru a prelua următoarele variabile. Sau specificați variabila între paranteze „$ {10}”, astfel încât bash să ia valorile împreună, nu ca $ 1 + 0.
Fără alte întrebări, salutări!
Multumesc pentru comentariul tau. Nu a reușit să explice utilizarea corectă a exit-ului, atât în script, cât și în funcții. În ceea ce privește $ 10, nu am legat niciodată atât de mult, așa că nu am dat peste acea problemă, este bine să știu că există o soluție pentru asta (am șters deja noul lucru învățat astăzi 😀).
Vă mulțumesc foarte mult pentru articol! Unele lucruri pe care le menționați încă nu au avut clarificări. De exemplu, getops.
În partea de ieșiri a ecranului, a trebuit să menționați pisica pe care o menționați mai târziu ...
pisică <
***************************************
* ACEASTA FORMĂ ESTE FOARTE EXPRESIVĂ *
***************************************
EOF
În exemplul dvs.:
pisică << EOF >> test.sh
Trebuie menționate două lucruri ... >> este „adăugați”, adică, dacă repetați aceeași comandă, veți avea întregul script în duplicat ... Ar trebui să utilizați doar unul ...
pisică << EOF> script.sh
Da, ar trebui să fie numit și script.sh
Apoi în
dacă [-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "–help"]]; atunci
ajutor
fi
Cred că ar trebui scris ...
dacă [[-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "–help"]]; atunci
...
Există mult mai multe de descoperit de la BASH.
Ai putea să-l intitulezi „BAZI” 🙂
De exemplu, parametrii „testeri” ca -z pentru a vedea dacă sunt goi, sau -f pentru a vedea dacă există ca fișier.
Din nou, vă mulțumesc pentru efortul depus.
alberto
Un tutorial de script bash foarte bun!
-- CODARE: UTF-8 --
Este prima dată când văd acea linie pentru a seta codificarea caracterelor într-un script bash. Pare mai tipic pentru Python decât Bash. Chiar este necesar? Am căutat o referință pe Google, dar nu găsesc nimic, aveți la îndemână un link care să vorbească despre această chestiune? Mai exact cu privire la adecvarea acelei linii.
În opinia mea, pentru a scrie scripturi în Bash folosind UTF-8, trebuie doar să salvați fișierul text ca atare (fără BOM) și să aveți anumite variabile de mediu, (LANG și LC_ *), setate corect.
Apoi, evident, este necesar ca comenzile executate să fie pregătite pentru alte codificări decât ASCII. De exemplu, dacă vrem să mergem cu majuscule, acest lucru nu pare să funcționeze:
«Ecou áéíóú | tr az AZ »
o:
«Ecou áéíóú | tr [: lower:] [: upper:] »
și este mai bine să utilizați:
«Ecou áéíóú | awk '{print toupper ($ 0)}' ».
Despre "codare»A fost menționat în acest blog înainte:
Bash: cum să faci un script executabil
Scriptul utilitar post instalare
Cineva mă corectează, dar acea linie de codificare (# -- CODARE: UTF-8 --) Nu are nimic de-a face cu bash sau shell-ul: este o linie de comentariu (începe cu #) și servește pentru a spune editorului că folosim pentru a scrie scriptul (vim, emacs ...) codificarea fișierului.
De fapt, bash nu vede o astfel de linie, deoarece este o linie de comentarii.
Excelent tutorial, deoarece Sysadmin cunoaște Scripting în Bash este esențial, este util pentru orice.
Foarte foarte bine!
Salutări!
În cazul în care este util pentru oricine, iată câteva utilizări și exemple pentru a vă crea propriile Scripturi: https://github.com/reduardo7/hsabx
Foarte bine. Lucruri noi de adăugat la scripturile mele. Lucrul cu codificarea și lucrul cu printf nu îl aveau.
Mulțumesc!!!
Foarte bun articol! Îl păstrez pentru favorite, ar fi bine să corectez ceea ce nu este în regulă și chiar să îl extind cu mai mult conținut. O aplauză pentru toate aceste informații !!!!