Teoria Bash

/ bin / bash

0. Index

  1. Lucruri care se întâmplă majorității oamenilor
  2. Structura unui scenariu
  3. Imprimați pe ecran
  4. Citiți INPUT-ul utilizatorului
  5. Calcule în bash
  6. Termeni
  7. Bucle
  8. funcţii
  9. 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 «$ bash script.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
Dacă scriptul nostru este executabil, îl putem adăuga la PATH și îl putem executa de oriunde / folder pe computerul nostru. Pentru aceasta trebuie să adăugăm fie la .bashrc al utilizatorului nostru, fie la / etc / bashrc linia
BIN = "folder unde avem scripturile" PATH = "$ BIN $ PATH"
Este o regulă Bash să scrieți numele variabilelor cu majuscule. Mulți oameni nu respectă această regulă, dar pentru scripturile lungi este apreciat deoarece le fac mult mai lizibile

2. Structura unui script

  1. Cap
  2. Definiția variabilelor globale
  3. Ajutor
  4. funcţii
  5. 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.

Utilizarea celor 3 ghilimele cu ecou permite folosirea întreruperilor de linie fără a lăsa mesajul să fie afișat prin ecou. Pentru mesajele cu mai multe linii este mult mai convenabil să folosiți ecoul o singură dată.

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.

Pentru o discuție mai amplă puteți vizita această întrebare de la Unix & Linux pe Stack Exchange.

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"
Aveți grijă la atribuirea variabilelor. „$ VAR = content” va produce o eroare, nu pot fi lăsate spații între semnul egal, numele variabilei și conținut. Utilizarea corectă este „VAR = content”

5. Calcule în Bash

Pentru asta putem folosi «expr«Atâta timp cât nu este nevoie să facem calcule complexe. Trebuie menționate două lucruri, primul este că «expr»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 «expr»Utilizarea parantezelor duble:

VAR2 = $ (($ VAR1 / 100))
Pentru o explicație suplimentară despre «expr»Sau o alternativă care folosește numere întregi, puteți privi această intrare KZKG ^ gaara.

6. termeni

A fost deja scris într-un mod foarte extins despre «if""altfel""Elif»Și condiții. Puteți citi despre asta în:

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
În Bash "=" și "==" sunt interpretate ambele în același mod. Acest lucru nu se întâmplă în alte limbaje de programare în care „=” este utilizat numai pentru a atribui variabile.

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.

«Caz»Poate fi de asemenea folosit ca o secvență de«if«, Pentru aceasta trebuie să utilizați« ;; & »(continua) în loc de« ;; » (Stop).

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.

Puteți găsi mai multe despre funcții în [url = https: //blog.desdelinux.net/programando-en-bash-parte-3/] din acest articol Usemoslinux [/ url].

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).
Punctele duble inițiale trebuie să nu afișeze erori.

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.


Conținutul articolului respectă principiile noastre de etică editorială. Pentru a raporta o eroare, faceți clic pe aici.

20 comentarii, lasă-le pe ale tale

Lasă comentariul tău

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

*

*

  1. Responsabil pentru date: Miguel Ángel Gatón
  2. Scopul datelor: Control SPAM, gestionarea comentariilor.
  3. Legitimare: consimțământul dvs.
  4. Comunicarea datelor: datele nu vor fi comunicate terților decât prin obligație legală.
  5. Stocarea datelor: bază de date găzduită de Occentus Networks (UE)
  6. Drepturi: în orice moment vă puteți limita, recupera și șterge informațiile.

  1.   elav el a spus

    MASTERAL. Nu spun mai mult U_U

  2.   Miguel el a spus

    Buna articol foarte bun.
    Hei, ai pus să dai permisiuni sudo + x în loc de chmod + x

    1.    Henry el a spus

      $ sudo chmod + x script.sh
      (Pentru a fi mai exact, hehe)

      Ah, felicitări și mulțumesc!

  3.   ciocănit el a spus

    Foarte bună postare, chiar vă felicit, țineți-o așa, Salutări

  4.   Gustavo el a spus

    Ș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

  5.   american din America de Sud el a spus

    PIEȚĂ de tutelă. Excelent și foarte bine explicat.
    Mulţumesc.

  6.   Gabriel el a spus

    Post excelent pe tema 😉

  7.   Mario Guillermo Zavala Silva el a spus

    Foarte interesant și foarte important mulțumesc pentru informații….
    NOROC !!!

  8.   Nu din brooklyn el a spus

    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.

  9.   Adrian el a spus

    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!

    1.    Nu din brooklyn el a spus

      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 😀).

  10.   chanio el a spus

    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

  11.   clow_eriol el a spus

    Un tutorial de script bash foarte bun!

  12.   OCZ el a spus

    -- 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)}' ».

    1.    Nu din brooklyn el a spus

      Despre "codare»A fost menționat în acest blog înainte:

      Bash: cum să faci un script executabil
      Scriptul utilitar post instalare

    2.    borriquito ca tine el a spus

      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.

  13.   JoRgE-1987 el a spus

    Excelent tutorial, deoarece Sysadmin cunoaște Scripting în Bash este esențial, este util pentru orice.

    Foarte foarte bine!

    Salutări!

  14.   Eduardo Cuomo el a spus

    Î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

  15.   Lito negru el a spus

    Foarte bine. Lucruri noi de adăugat la scripturile mele. Lucrul cu codificarea și lucrul cu printf nu îl aveau.
    Mulțumesc!!!

  16.   xxxtonixxx el a spus

    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 !!!!