Bash teori

/ bin / bash

0. Indeks

  1. Ting som skjer med folk flest
  2. Struktur av et skript
  3. Skriv ut på skjermen
  4. Les brukerINNGANG
  5. Beregninger i bash
  6. Vilkår
  7. Sløyfer
  8. Funciones
  9. getops

1. Ting som skjer med folk flest

/ bin / bash eller / bin / sh

En av de første tingene maskinen gjør når man utfører skriptet vårt, er å se på hvilket skall det skal gjøre det med. På de fleste nåværende Linux-systemer / Bin / sh er en lenke til / bin / bash, men dette er ikke alltid tilfelle, for eksempel i distribusjoner som bruker opptattboks Traen Sh og vanligvis tar de også med seg Bash, men hvis du bruker / Bin / sh, den kjører ikke med Bash. Derfor anbefaler jeg alltid å bruke / bin / bash.

Unicode vs. ASCII

Har du noen gang lurt på hvorfor du ikke kan bruke "¿" eller "ñ" i manusene dine? Eller bruke aksenter? Det kan være ganske irriterende i interaktive skript. Det er fordi standardkodingen av Bash er ASCII, eller hva som er det samme, det engelske tegnsettet. For å endre det, trenger vi bare å fortelle skriptet vårt at vi vil bruke Unicode. For det må du legge til en linje like etter kommandotolken:

# - * - KODING: UTF-8 - * -

Vær forsiktig, det er viktig at denne linjen er i begynnelsen av skriptet.

Gjør skriptet kjørbart

Det er morsomt hvor mange som kjører manusene med «$ bashscript.sh" i stedet for "$ ./script.sh'Det er tross alt det vi har definert et skall for.

For å legge til kjøringstillatelser, må du utføre:

sudo + x script.sh
Hvis skriptet vårt er kjørbart, kan vi legge det til PATH og gjøre det kjørbart hvor som helst / mappe på datamaskinen vår. For det må vi legge til enten .bashrc til brukeren vår eller til / etc / bashrc linjen
BIN = "mappe der vi har skriptene" PATH = "$ BIN $ PATH"
Det er en Bash-regel å skrive variabelnavn i stor bokstav. Mange følger ikke denne regelen, men for lange manus blir det verdsatt fordi de gjør dem mye mer lesbare

2. Struktur av et manus

  1. Hodegavl
  2. Definisjon av globale variabler
  3. Hjelp
  4. Funciones
  5. Hoveddelen

Overskriften er der vi indikerer hvilket skall vi vil bruke og kodingen. Fordelen med funksjonene er å gjenbruke kode som gjentas ved å skrive den bare én gang og gjøre det lettere å forstå skriptet, for kode som overstiger 100 linjer er det veldig nyttig.

For å kunne bruke funksjoner, må de defineres med før hoveddelen av skriptet vårt. Og hvis vi vil bruke variabler på globalt nivå gjennom hele skriptet, både i hoveddelen og i funksjonene, må vi definere dem i begynnelsen av alt, like etter overskriften.

Til slutt er det god praksis å skrive en hjelperfunksjon for når skriptet vårt kjører dårlig eller med dårlige parametere. Åpenbart vil vi i de tilfellene avslutte skriptet umiddelbart uten å lese funksjonene. For det kan vi bruke:

funksjonshjelp () {ekko "" "Vår velformaterte hjelpetekst." "" avslutt hvis [[-z $ 1 || $ 1 == "-h" || $ 1 == "--hjelp"]]; så hjelp fi

Hvis vi legger til "exit" i hjelpefunksjonen, vil vi avslutte skriptet hver gang vi kjører hjelp, for eksempel etter feilmeldinger osv. Vi sparer noen få kodelinjer.

Betingelsen indikerer visningshjelp på skjermen og avslutt hvis skriptet kjøres uten parametere eller hvis -h / –help er spesifisert. Hvis du ser på det, er det standardoppførselen til de fleste linux-programmer.

Bruk av de 3 anførselstegnene med ekko gjør det mulig å bruke linjeskift uten å la meldingen vises med ekko. For meldinger med flere linjer er det mye mer praktisk å bruke ekko bare en gang.

3. Skriv ut på skjermen

Det er to hovedkommandoer for utskrift til skjerm i bash: «savner»Y«printf«. De er begge like raske, og begge er en del av bash. Hovedforskjellen for en nybegynner er at ekko legger til en ny linje på slutten, mens «printf"Gjør ikke.

Ekko er veldig bra og er det folk flest bruker, men når du leser brukerens INNGANG, eller når du vil skrive ut variabler hentet fra filer ved tekstbehandling, kan rare ting skje. De løses vanligvis lett, like enkelt som å endre doble anførselstegn til enkelt eller omvendt, eller ta de variable referansene ut av anførselstegnene. «Echo»Gjør rare ting også avhengig av hvordan det ble samlet, hvis vi alltid bruker Ubuntu eller alltid Fedora, påvirker det ikke oss, men hvis vi endrer distribusjonen gjør det.

Det er derfor jeg bruker «printf«, Som ikke gir meg hodepine og oppfører seg mer som«printf»Fra C eller«skrive ut»Av Python er dette veldig viktig hvis du noen gang vil portere skriptet ditt til et annet programmeringsspråk.

For en mer omfattende diskusjon kan du besøke dette spørsmålet fra Unix & Linux på Stack Exchange.

4. Les brukerINNGANG

Alt vi skriver etter navnet på skriptet vårt og før vi trykker på ENTER-tasten lagres automatisk i spesielle variabler. Disse variablene er av typen $ X der X er et tall.

«$0»Angir navnet på skriptet vårt og fra«$1»Alt det vi har skrevet senere er uendelig variabelt. For eksempel:

cat << EOF >> test.sh #! / bin / bash # - * - KODING: UTF-8 - * - printf "\ $ 0 = $ 0 \ n" printf "\ $ 1 = $ 1 \ n" printf "\ $ 2 = $ 2 \ n" EOF chmod + x script.sh ./script.sh filen.txt

Vi oppretter et testskript, gjør det kjørbart og kjører det med to parametere. Vi får skjermutdata fra:

$ 0 = ./script.sh $ 1 = min $ 2 = file.txt

Ved å bruke anførselstegn kunne vi ha sendt "min fil.txt" til "$ 1".

Vi kan også lese INNGANGEN til en bruker med "lese" -kommandoen, som direkte indikerer variabelen der vi vil lagre parameteren. For eksempel:

printf "Hva heter du? \ n" les NAME printf "Hei, $ NAME. \ n"
Vær forsiktig med tildeling av variabler. "$ VAR = innhold" vil gi en feil, ingen mellomrom kan være igjen mellom likhetstegnet, variabelnavnet og innholdet. Riktig bruk er "VAR = innhold"

5. Beregninger i Bash

Til det kan vi bruke «ekspr«Så lenge vi ikke trenger å gjøre komplekse beregninger. To ting skal bemerkes, den første er at «ekspr»Bare innrømmer hele tall, det andre er at inndelingen returnerer hele resultatet, for å se resten vi kan bruke«%".

Vanligvis vil vi tildele resultatet av expr til en variabel. Vi kan gjøre det på to måter:

VAR2 = `expr $ VAR1 / 10` VAR2 = $ (expr $ VAR1 / 100)

Du kan også hoppe over «ekspr»Bruke doble parenteser:

VAR2 = $ (($ VAR1 / 100))
For en nærmere forklaring på «ekspr»Eller et alternativ som bruker hele tall, kan du se på denne KZKG ^ gaara-oppføringen.

6. vilkår

Det er allerede skrevet på en meget omfattende måte om «if" 'ellers" 'elif»Og forhold. Du kan lese om det i:

Jeg vil bare trekke frem forskjellen mellom bruk av enkle firkantede parenteser, «[]«, Og doble parenteser,«[[]]«, For forholdene. Med doble braketter kan vi bruke tilleggsbetingelser:

  • «&&»For og
  • «||»For eller

Å bruke "&&»Y«||»Med enkle firkantede parenteser, bør hver del skilles i separate firkantede parenteser. Eksemplet som brukes for den delen av skriptet som ser for å se om hjelp må utføres, er:

hvis [-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "--hjelp"]]; så hjelp fi

Det sparer oss også fra å måtte skrive variabelnavn i anførselstegn for å forhindre feil. For eksempel:

hvis [$ 1 = 1]; deretter printf "Parameteren er lik 1."; fi if ["$ 1" = 1]; deretter printf "Parameteren er lik 1."; fi hvis [[$ 1 = 1]]; deretter printf "Parameteren er lik 1."; fi

Hvis script.sh kjøres uten noen parametere, vil det første tilfellet gi en feil:

bash: [: =: forventet unary operatør
I Bash tolkes begge "=" og "==" på samme måte. Dette skjer ikke i andre programmeringsspråk der "=" bare brukes til å tilordne variabler.

Det som ikke har blitt snakket om er «saken«, Brukes til å forenkle«if«. La oss begynne på begynnelsen når vi ikke har noen «if»All koden blir utført. Hvis vi legger til en betingelse «if»Vi vil ha to tilfeller, en der kodeblokken inne i«if»Og det andre tilfellet der denne blokken ikke blir utført.

Hvis vi legger til en «ellers«Vi vil også ha to saker, men disse to sakene er forskjellige fra de forrige. For nå vil det være to betingede kodeblokker, A og B, og en C-blokk, som er resten av programmet. A eller B vil bli henrettet, og C. I forrige tilfelle var det A og C eller bare C.

For å unngå skrivevilkår «hvis / annet"innenfor"ellers»Og for å forenkle lesingen av koden, ble den opprettet«elif«. Når vi har mange forhold som avhenger av den forrige, for eksempel tallrekke eller typen:

VAR1 = $ 1 hvis [[$ VAR1 = 1]]; deretter printf "1 \ n" elif [[$ VAR1 = 2]]; deretter printf "2 \ n" elif [[$ VAR1 = 3]]; deretter printf "3 \ n" annet printf "none \ n" fi

Når det gjelder den siste «elif»Mange forhold vil bli lest. I tilfelle er denne prosessen strømlinjeformet:

VAR1 = $ 1 sak $ VAR i 1) printf "1 \ n" ;; 2) printf "2 \ n" ;; 3 | 4) printf "3 eller 4, det kommer an \ n" ;; *) printf "ingen \ n" ;; at C

En variabel vil bli lest, i dette tilfellet VAR1, og det vil bli sjekket om den tilsvarer noen av tilfellene, hvis ikke, vil standardtilfellet "*" bli utført. Dobbelt semikolon tilsvarer «bryte", De forteller"saken»Det må ta slutt.

«Sak»Kan også brukes som en sekvens av«if«, For det må du bruke« ;; & »(fortsett) i stedet for« ;; » (Stoppe).

7. Sløyfer

Svært få sløyfer er kjent på noe programmeringsspråk. I Bash er de «mens" 'til»Y«forum«. Det er allerede skrevet i bloggen om disse:

Det er to typer løkker «forum«, De som er av typen«$ for VAR i LOQUESEA»Og hva er av type C«$ for ((I = 0; I <= 10; I ++))«. Den andre typen løkker «forum»Er veldig nyttige, den har 3 deler i begynnelsen av løkken:

  • Erklæring og initiering av variabler (I dette tilfellet en hjelpevariabel "I = 0").
  • Utførelsesbetingelse (til jeg er mindre enn eller lik 10).
  • Økning av hjelpevariabelen

Etter min mening er det den mektigste sløyfen av alle. Et eksempel som skriver ut alle tall fra 0 til 10, inkludert:

#! / bin / bash for ((I = 0; I <= 10; I ++)); gjør printf "$ I \ n" ferdig

8. Funksjoner

Det er noen ting som Bash ikke tillater oss å gjøre, ikke sant? Ved første øyekast hindrer bash-funksjoner deg i å gjøre tre ting: å erklære lokale variabler i funksjoner, overføre parametere til funksjoner og returnere parametere. Alt har en løsning.

Gjør ingenting som:

#! / bin / bash VAR = 1 printc "$ VAR \ n" -funksjon hallo () {VAR = 2 printf "$ VAR \ n"} hallo printf "$ VAR \ n"

Dette skrives ut på skjerm 1, 2 og 2.

For å erklære lokale variabler, legg til «lokal»Når du erklærer:

#! / bin / bash VAR = 1 printf "$ VAR1 \ n" funksjon foo () {local VAR1 = 2 printf "$ VAR1 \ n"} printf "$ VAR1 \ n" foo printf "$ VAR1 \ n"

Dette skriver ut 1, 1, 2, 1 til skjermen.

Hvordan overfører du parametere til en funksjon?

#! / bin / bash # - * - KODING: UTF-8 - * - funksjon hei () {printf "Hei $ 1 \ n"}

printf "Hva heter du? \ n"
les VAR1
hei $ VAR1

Hvordan returneres parametere?

#! / bin / bash # - * - KODING: UTF-8 - * - funksjon hallo () {printf "Hello holita"} printf "Hva heter du? \ n" les VAR1 VAR1 = $ (hallo) # HER ER DET printf "$ VAR1 $ VAR2 \ n"

Som du kan se, har dette to ulemper, du kan bare returnere en parameter, som kan være en vektor 😀, og hvis du vil returnere en parameter, kan du ikke lenger skrive ut på skjermen fra den funksjonen.

Du kan finne flere ting om funksjoner på [url=https://blog.desdelinux.net/programando-en-bash-parte-3/]denne artikkelen fra Usemoslinux[/url].

9. Getops

En av de siste tingene du trenger å vite om Bash for å lage komplekse skript er «getops«. Den brukes til å overføre alternativer til skriptet uansett rekkefølge. Den eneste ulempen er at den bare påvirker korte alternativer:

#! / bin / bash # - * - KODING: UTF-8 - * - VARC = 0 funksjonshjelp () {printf "Hjelpemelding \ n" avslutt} hvis [[-z $ 1]]; så hjelp fi mens getopts: ha: b: c OPT; gjør saken $ OPT i h) hjelp ;; :) hjelp ;; a) VARA = $ OPTARG ;; b) VARB = $ OPTARG ;; c) VARC = 1 ;; \?) hjelp ;; esac done # Hovedblokk av skriptet som # gjør ting med VARA, VARB og VARC

«getopts»Les alternativene en etter en, så det kreves en løkke.

Det er to typer alternativer som kan overføres ved hjelp av «getopts':

  • Parametere kalt flagg, i dette tilfellet -c eller -h. De er spesifisert med bokstaven vi vil bruke. De er som boolske variabler, «sant»(Are) eller«falsk"(De er ikke her).
  • Parametere med tilhørende argumenter, -a hva som helst, -b hva som helst. De er spesifisert med bokstaven vi ønsker med et kolon nedenfor. Argumentet er lagret i OPTARG (dette navnet kan ikke endres).
De første dobbeltpunktene skal ikke vise noen feil.

Hva gjør dette skriptet?

Viser hjelpemeldingen når ingen valg sendes, når parameteren "-h" sendes, når en ugyldig parameter sendes (for eksempel "-x", gjøres dette med "\?") Eller når en gyldig parameter uten argument (":"). I resten av tilfellene sparer det tilstedeværelsen av "-c" som en 1 i VARC, og verdiene overført med "-a" og "-b" i VARA og VARB.


Legg igjen kommentaren

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *

*

*

  1. Ansvarlig for dataene: Miguel Ángel Gatón
  2. Formålet med dataene: Kontroller SPAM, kommentaradministrasjon.
  3. Legitimering: Ditt samtykke
  4. Kommunikasjon av dataene: Dataene vil ikke bli kommunisert til tredjeparter bortsett fra ved juridisk forpliktelse.
  5. Datalagring: Database vert for Occentus Networks (EU)
  6. Rettigheter: Når som helst kan du begrense, gjenopprette og slette informasjonen din.

  1.   livlig sa

    MESTLIG. Jeg sier ikke mer U_U

  2.   Miguel sa

    Hei veldig god artikkel.
    Hei du satte for å gi tillatelser sudo + x i stedet for chmod + x

    1.    Henry sa

      $ sudo chmod + x script.sh
      (For å være mer nøyaktig, hehe)

      Ah, gratulerer og takk!

  3.   brannkaldt sa

    Veldig bra innlegg, sannheten er at jeg gratulerer deg, fortsett, Hilsen

  4.   Gustavo sa

    Og hvis du vil at skriptet skal være synlig når det kjøres, trinn for trinn, for eksempel å se hvordan variabler, betingelser og alt oppfører seg, kan du bruke:

    sh -x skript

    Hilsen

  5.   Dago sa

    STYKK av veiledning. Utmerket og veldig godt forklart.
    Takk.

  6.   Gabriel sa

    Utmerket innlegg om emnet 😉

  7.   Mario Guillermo Zavala Silva sa

    Veldig interessant og viktig, takk for informasjonen ....
    JUBEL !!!

  8.   Ikke fra Brooklyn sa

    Takk alle for gratulasjonene dine, for Miguel-kommandoen, han lar meg ikke endre oppføringen når den er publisert. Jeg må forestille meg det.

  9.   Adrian sa

    Veldig bra!

    Først av alt ønsket jeg å gratulere deg med innlegget, jeg syntes det var lett å forstå, og det hjelper virkelig å følge retningslinjene for å programmere godt i bash, spesielt for folk som begynner å programmere.

    Imidlertid har jeg funnet et par detaljer som jeg mener bør rettes.

    Først: i seksjon «2. STRUKTUR AV ET SKRIPT »funksjonen er ikke lukket, noe som vil føre til problemer når den kjøres i et skript.
    Løsningen vil være å legge til en lukkestang til den like etter "exit" -kommandoen.

    For det andre: i seksjon «4. LES BRUKERINNGANGEN ”du bekrefter at parameterne som brukeren kan angi varierer fra $ 0 til uendelig, men“ bash ”tolker bare fra $ 0 til $ 9, siden $ 10 vil være lik $ 1 + 0.
    For å løse dette problemet kan du enten bruke kommandoen "shift" til å hente følgende variabler. Eller spesifiser variabelen i parentes "$ {10}", slik at bash tar verdiene sammen, ikke som $ 1 + 0.

    Uten videre, hilsen!

    1.    Ikke fra Brooklyn sa

      Takk for kommentaren. Det mislyktes helt å forklare riktig bruk av exit, både i skriptet og i funksjonene. Når det gjelder $ {10} har jeg aldri testamentert så mye, så jeg har ikke fått det problemet, det er godt å vite at det er en løsning på det (jeg har allerede krysset av det nye som ble lært i dag 😀).

  10.   chanio sa

    Tusen takk for artikkelen! Noen ting du nevner manglet fremdeles avklaring. For eksempel getops.
    I delen av skjermutgangene måtte du nevne katten som du senere nevnte ...
    katt <
    ***************************************
    * DETTE SKJEMAET ER VELDIG UTRYKTIG *
    ***************************************
    EOF

    I eksemplet ditt:
    katt << EOF >> test.sh
    To ting bør nevnes ... >> det er "legg til" det vil si at hvis du gjentar den samme kommandoen, vil du ha hele skriptet i duplikat ... Du bør bare bruke en ...
    katt << EOF> script.sh
    Ja, det skal også kalles script.sh
    Så inn
    hvis [-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "–hjelp"]]; deretter
    hjelpe
    fi

    Jeg synes det skal skrives ...
    hvis [[-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "–hjelp"]]; deretter
    ...

    Det er mye mer å oppdage fra BASH.
    Kan du gi den tittelen "BASICS"? 🙂
    For eksempel, parameter 'testere' som -z for å se om de er tomme, eller -f for å se om den eksisterer som en fil.

    Takk igjen for innsatsen.
    alberto

  11.   clow_eriol sa

    En veldig god bash script tutorial!

  12.   OCZ sa

    -- KODING: UTF-8 --

    Det er første gang jeg har sett den linjen for å sette tegnkoding i et bash-skript. Det virker mer som Python enn Bash. Er det virkelig nødvendig? Jeg har søkt etter en referanse på Google, men jeg finner ikke noe. Har du en lenke for hånden som snakker om denne saken? Spesielt på egnetheten til den linjen.

    Etter min mening, for å skrive skript i Bash ved bruk av UTF-8, trenger du bare å lagre tekstfilen som sådan (uten BOM) og ha visse miljøvariabler, (LANG og LC_ *), riktig innstilt.
    Så er det åpenbart nødvendig at de utførte kommandoene er forberedt på andre kodinger enn ASCII. Hvis vi for eksempel vil gå til store bokstaver, ser det ikke ut til å fungere:
    «Ekko áéíóú | tr az AZ »
    o:
    «Ekko áéíóú | tr [: nedre:] [: øvre:] »
    og det er bedre å bruke:
    «Ekko áéíóú | awk '{print toupper ($ 0)}' ».

    1.    Ikke fra Brooklyn sa

      Om «koding»Har blitt nevnt i denne bloggen før:

      Bash: hvordan lage et skript som kan kjøres
      Post installasjonsverktøy skript

    2.    borriquito som deg sa

      Noen retter meg, men den kodende linjen (# -- KODING: UTF-8 --) Det har ingenting å gjøre med bash eller skallet: det er en kommentarlinje (begynner med #) og tjener til å fortelle redaktøren at vi bruker til å skrive skriptet (vim, emacs ...) kodingen av filen.

      Bash ser faktisk ikke en slik linje, fordi det er en kommentarlinje.

  13.   JORGE-1987 sa

    Utmerket opplæring, ettersom Sysadmin å vite skript i Bash er viktig, er det nyttig for alt.

    Veldig veldig bra!

    Greetings!

  14.   Edward Cuomo sa

    Hvis det er nyttig for noen, er det flere bruksområder og eksempler for å lage dine egne skript: https://github.com/reduardo7/hsabx

  15.   Lito Black sa

    Veldig bra. Nye ting å legge til i skriptene mine. Encodig ting og printf ting hadde ikke det.
    Takk skal du ha!!!

  16.   xxxtonixxx sa

    Sååå god artikkel! Jeg holder denne for favoritter, det ville være fint å rette opp det som er galt og til og med utvide det med mer innhold. En applaus for all denne informasjonen !!!!