Bash Shell Expansions Brace Expansion, parameterutvidelse og mer

Bash Shell Expansions Brace Expansion, parameterutvidelse og mer
I denne artikkelen vil vi dekke alle de grunnleggende funksjonene i utvidelse av bash shell. Noen av de mest komplekse og interessante utvidelsene er utvidelse av stagutvidelse og parameter som har mange funksjoner og alternativer som er kraftige, men bare mestret over tid av bash -programmerere og Linux DevOps folk. Ordsplitting er også ganske interessant og oversett en gang. Filnavn, aritmetisk ekspansjon og variabel substitusjon er velkjent. Vi vil dekke mange emner og vise eksempler på kommandoen og mest nyttige syntaks for hver syntaks. Så la oss komme i gang.
  • Miljø
  • Kommandosubstitusjon
  • Prosess substitusjon
  • Variabel substitusjon
  • Stagutvidelse
  • Parameterutvidelse
  • Posisjonsparametere
  • Tilde -utvidelse
  • Aritmetisk substitusjon
  • Ord splitting
  • Filnavnutvidelse
  • Konklusjon

Miljø

For å teste alle Bash Shell -utvidelsesfunksjonene må vi sørge for at vi kjører en nylig versjon av Bash. Nedenfor er systeminformasjonen for denne artikkelen. Testene i denne artikkelen kjører på Ubuntu 19.10 som vist nedenfor.

$ uname -a
Linux forekomst-1 5.3.0-1014-GCP #15-UBUNTU SMP TUE 3. mars 04:14:57
UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Bash -versjonen for disse testene er bash versjon 5, som er ganske nylig. Eldre versjoner av bash mangler en haug med funksjoner.

$ Bash -Versjon
Gnu Bash, versjon 5.0.3 (1) -Release (x86_64-PC-Linux-GNU)
Copyright (C) 2019 Free Software Foundation, Inc.
Lisens GPLV3+: GNU GPL versjon 3 eller nyere

Kommandosubstitusjon

Kommandosubstitut. Kommandosubstitusjon har to syntakser; Den mer populære syntaksen er backtick -syntaksen der kommandoen som skal utføres er vedlagt i to backquotes, eller backticks. Den andre syntaksen som er like kraftige omslutter kommandoer i $ () syntaks, og utgangen kan brukes fra den nye utvidelsen. La oss se på en rekke eksempler på kommandosubstitusjon nedenfor.

Enkel kommandosubstitusjon ved hjelp av $ () syntaks for å kjøre datakommandoen.

$ ekko $ (dato)
Ons 18. mars 01:42:46 UTC 2020

Enkel kommandosubstitusjon ved bruk av backtick syntaks for å kjøre datakommandoen.

$ ekko 'Dato'
Ons 18. mars 01:43:17 UTC 2020

Å bruke STDIN -operatøren i begynnelsen av syntaks for kommandosubstitusjoner er en fancy måte å lese teksten til en fil til en variabel og bruke den i en kommando på skallet som nedenfor.

$ ECHO "Hello World"> MyText
$ ekko $ (< mytext)
Hei Verden

Les en fil i en variabel som skal brukes i en kommando ved hjelp av CAT -kommandoen og kommandosubstitusjonen.

$ ECHO "Hello World"> MyText
$ ekko $ (Cat MyText)
Hei Verden

Samme som ovenfor, les en fil og bruk den i kommandosubstitusjon ved hjelp av backticks og CAT -kommando.

$ ECHO "Hello World"> MyText
$ ECHO 'CAT MYTEXT'
Hei Verden

Kombiner innebygd kommandosubstitusjon med en annen kommandosubstitusjon ved å bruke både $ () og backticks sammen

$ ekko 'ekko $ (dato) | cut -d "" -f 1'> myfile
$ katt myfile
Ons

Innebygd kommandosubstitusjon i en annen ved hjelp av to $ () syntaksoperasjoner

$ ekko "i dag er $ (ekko $ (dato) | cut -d" "-f 1)"> myfile
$ katt myfile
I dag er ons

Bruk output fra en kommando som argumenter til en annen kommando, med backtick -syntaks. Vi får en liste over filer ved å kjøre CAT som inneholder en fil per linje og deretter sende den inn i RM -kommandoen som vil fjerne hver fil

$ berør en; berør to
$ ekko en> myfiler; ekko to >> myfiler
$ RM 'Cat Myfiles'

Samme som ovenfor, men med $ () syntaks, pass -kommandoutgangen fra CAT til RM -kommando for å slette filer.

$ berør en; berør to
$ ekko en> myfiler; ekko to >> myfiler
$ RM $ (Cat Myfiles)

Lagre utgangen fra en CAT -kommando til en variabel og sløyfe deretter gjennom variabelen, slik at du tydeligere kan se hva som skjer.

$ berør en; berør to
$ ekko en> myfiler; ekko to >> myfiler
$ Myfiles = $ (Cat Myfiles)
$ for f i $ myfiles; gjør ekko $ f; rm $ f; Ferdig
en
to

Samme som ovenfor, men bruker syntaks for backticks for å kjøre CAT -kommandoen og lagre utgangen i en variabel og deretter sløyfe gjennom filene i variabelen.

$ berør en; berør to
$ ekko en> myfiler; ekko to >> myfiler
$ Myfiles = 'katt myfiles'
$ for f i $ myfiles; gjør ekko $ f; rm $ f; Ferdig
en
to

Bruk kommandosubstitusjonen med STDIN -operatøren til å lese en fillinje for linje i en variabel og deretter sløyfe gjennom variabelen etterord

$ berør en; berør to
$ ekko en> myfiler; ekko to >> myfiler
$ Myfiles = $ (< myfiles)
$ for f i $ myfiles; gjør ekko $ f; rm $ f; Ferdig
en
to

Prosess substitusjon

Prosesssubstitusjon er et dokumentert trekk ved bash; Det er ganske kryptisk etter min mening. Jeg har faktisk ikke funnet mange saker med god bruk å anbefale for det. Et eksempel er inkludert her for fullstendighet der vi bruker prosesserstatning for å få utdataene fra en kommando og deretter bruke den en annen kommando. Vi skriver ut listen over filer i omvendt rekkefølge med sort -kommando i dette eksemplet etter å ha hentet filer fra LS -kommandoen.

$ berør en.tekst; berør to.tekst; berør tre.tekst
$ sorter -r <(ls *txt)
to.tekst
tre.tekst
en.tekst

Variabel substitusjon

Variabel substitusjon er det du kan vurdere grunnleggende bruk av variabler og erstatte verdien av variabelen når den refereres til. Det er ganske intuitivt, noen få eksempler er gitt nedenfor.

Enkel variabel tildeling og bruk der vi legger en streng i variabel x og deretter skriver den ut til stdout

$ X = 12345
$ ekko $ x
12345

Sjekk om en variabel er tildelt noe eller null, i dette tilfellet er den tildelt, så vi skriver den ut til stdout

$ X = 12345
$ hvis [-z "$ x"]; da ekko "x er null"; ellers ekko $ x; fi
12345

Sjekk om en variabel er tildelt noe eller null, i dette tilfellet er den ikke satt, så vi skriver ut "er null" i stedet for verdien.

$ unset x
$ hvis [-z "$ x"]; da ekko "x er null"; ellers ekko $ x; fi
X er null

Stagutvidelse

Brace Expansion er et superkraftig trekk ved bash som lar deg skrive mer kompakte skript og kommandoer. Den har mange forskjellige funksjoner og alternativer beskrevet nedenfor. Innen seler tolkes syntaksen din til en mer ordentlig syntaks, avhengig når du går inn i krøllete seler. La oss se på en rekke eksempler for utvidelse av stag.

Hver versjon av elementene i listen i seler blir utført. Så vi går fra en Echo -kommando og skriver ut 3 versjoner av ordet nedenfor atskilt med mellomrom.

$ ekko a, m, p _warehouse
A_WAREHOUSE M_WAREHOUSE P_WAREHOUSE

Uttrykk i utvidelsen forårsaker utførelse flere ganger. For å bevise dette bruker vi datoen og søvnkommandoen for å validere at datakommandoen kjøres en gang for hver iterasjon av mønsteret i stagutvidelsen.

$ ekko a, m, p _ $ (dato; søvn 1)
A_SUN 22. mars 18:56:45 UTC 2020 M_SUN 22. mars 18:56:46 UTC
2020 P_SUN 22. mars 18:56:47 UTC 2020

Utvidelser ved å bruke tall med ... vil føre til at sekvensielle tall utvides i en numerisk sekvens

$ ekko 1… 8 _warehouse
1_warehouse 2_warehouse 3_warehouse 4_warehouse 5_warehouse 6_warehouse 7_warehouse
8_warehouse

Omvendt ordrestangutvidelse med sekvens av tall

$ ekko 8… 1 _warehouse
8_warehouse 7_warehouse 6_warehouse 5_warehouse 4_warehouse 3_warehouse 2_warehouse
1_warehouse

Bruke en valgfri økningsverdi for å spesifisere de numeriske trinnene i Brace Expansion

$ ekko 1… 9… 3 _warehouse
1_warehouse 4_warehouse 7_warehouse

Leksikografisk utvidelse

$ ekko a… e _warehouse
A_warehouse B_warehouse C_warehouse D_Warehouse E_Warehouse

Omvendt ordre leksikografisk stagutvidelse

$ ekko e ... a _warehouse
e_warehouse d_warehouse c_warehouse b_warehouse a_warehouse

Leksikografisk utvidelse

$ ekko a… z… 5 _warehouse
A_warehouse F_warehouse K_warehouse P_warehouse U_Warehouse Z_warehouse

Multiplikativ utvidelse av stag med 2 stagutvidelser i en kommando

$ ekko a… e 1… 5 _warehouse
A1_warehouse A2_warehouse A3_Warehouse A4_Warehouse A5_Warehouse B1_Warehouse
B2_warehouse B3_Warehouse B4_Warehouse B5_Warehouse C1_Warehouse C2_Warehouse
C3_Warehouse C4_Warehouse C5_Warehouse D1_Warehouse D2_Warehouse D3_Warehouse
d4_warehouse d5_warehouse e1_warehouse e2_warehouse e3_warehouse e4_warehouse
e5_warehouse

Stagutvidelse for å bruke den samme roten to ganger i en kommando. Dette skaper en foo.TGZ TAR -fil fra en katalog under navn Foo. Det er en praktisk syntaks der du bruker den inne i en annen sløyfe og vil anta at basen av ordet brukes flere ganger. Dette eksemplet viser det med tjære, men det kan også brukes med MV og CP i henhold til dette eksemplet.

$ mkdir foo
$ Touch foo/foo a… e
$ tar czvf foo .tgz,
foo/
foo/foob
Foo/FOOC
foo/fooa
foo/mat
foo/fooe

Parameterutvidelse

Parameterutvidelse er også en fin kompakt syntaks med mange muligheter som: Tillat skript å angi standardverdier for usettede variabler eller alternativer, strengundersøkingsoperasjoner, søke og erstatte substitusjoner og andre brukssaker. Eksempler er nedenfor.
Sjekk for null og bruk parameteren hvis ikke null eller standardverdien. I dette tilfellet er X ikke null, så det vil bli brukt

$ X = 1
$ ekko $ x: -2
1

Sjekk for null og bruk parameteren hvis ikke null eller standardverdien. I dette tilfellet er x null, så standardverdien vil bli brukt

$ unset x
$ ekko $ x: -2
2

Sjekk om variabelen er null og sett og ekko den hvis den er null. X er tildelt 2 og trykt $ x. Dette kan både angi variabelen og bruke den i kommandoen med $ : = syntaks.

$ unset x
$ hvis [-z "$ x"]; så ekko null; fi
NULL
$ ekko $ x: = 2
2
$ hvis [-z "$ x"]; så ekko null; ellers ekko $ x; fi
2

Substring -ekspansjon vil erstatte et forskyvningspunkt Et visst antall tegn i strengen

$ X = "Hello World"
$ ekko $ x: 0: 7
Hei w

Endre forskyvningen til det andre tegnet og skriv ut 7 tegn på Substring

$ X = "Hello World"
$ ekko $ x: 1: 7
Ello Wo

Substring fra begynnelsen av strengen, men kuttet av de siste 2 tegnene

$ X = "Hello World"
$ ekko $ x: 0: -2
Hei Wor

Få en strenglengde med denne versjonen av parameterutvidelse

$ X = "Hello World"
$ ekko $ #x
11

Søk og erstatt i en variabel. I dette eksemplet erstatt den første små og store bokstaver O

$ X = "Hello World"
$ ekko $ x/o/o
Hei Verden

Søk og erstatt i en variabel, men med alle kamper erstattet på grunn av den ledende skråstreken i søkemønsteret.

$ X = "Hello World"
$ ekko $ x // o/o
Hei Verden

Mønstre som starter med #, betyr at kampen må starte i begynnelsen av strengen for å bli erstattet

$ X = "Hello World"
$ ekko $ x/#h/j
Jello World

Eksempel der det er å søke etter kamp i begynnelsen av strengen, men mislykkes fordi kampen er senere i strengen

$ X = "Hello World"
$ ekko $ x/#w/j
Hei Verden

Mønstre som begynner med % vil bare samsvare på slutten av strengen som i dette eksemplet.

$ X = "Hello World"
$ ekko $ x/%d/d i dag
Hei verden i dag

Eksempel for slutt på strengkampen som mislykkes fordi kampen er i begynnelsen av strengen.

$ X = "Hello World"
$ ekko $ x/%h/i dag
Hei Verden

Bruk Shopt med Nocasematch for å gjøre ensfølsom utskifting.

$ shopt -s nocasematch
$ X = "Hello World"
$ ekko $ x/hallo/velkommen
Velkommen verden

Slå av butikken med nocasematch for å gjøre sensitiv erstatning.

$ shopt -u nocasematch
$ X = "Hello World"
$ ekko $ x/hallo/velkommen
Hei Verden

Søk etter miljøvariabler som samsvarer med et mønster.

$ My_a = 1
$ My_b = 2
$ My_c = 3
$ ekko $ !MIN*
My_a my_b my_c

Få en liste over matchende variabler og sløyfe deretter gjennom hver variabel og skrive ut verdien

$ My_a = 1
$ My_b = 2
$ My_c = 3
$ variabler = $ !MIN*
$ for i i $ variabler; gjør ekko $ i; ekko "$ !i "; ferdig
My_a
1
My_b
2
My_c
3

Lag en streng hele store bokstaver

$ X = "Hello World"
$ ekko $ x ^^
HEI VERDEN
Lag en streng alle små bokstaver
$ X = "Hello World"
$ ekko $ x ,,
Hei Verden
Lag første karakter av en streng store bokstav
$ X = "George Washington"
$ ekko $ x^
George Washington
Lag første karakter av en små små bokstaver
$ X = Bob
$ ekko $ x,
Bob

Posisjonsparametere

Posisjonsparametere er normalt sett på som kommandolinjeparametere, hvordan du bruker dem vises med eksempler nedenfor.

Parameter $ 0 er skriptnavnet som kjører og deretter $ 1, $ 2, $ 3 osv. Er kommandolinjeparametere overført til et skript.

$ katteskript.sh
ekko $ 0
ekko $ 1
ekko $ 2
ekko $ 3
$ bash ./manus.Sh Apple Banana Carrot
./manus.sh
eple
banan
gulrot

Parameter $* er en enkelt variabel med alle kommandolinjens argumenter sammenkoblet.

$ katteskript.sh
ekko $ 1
ekko $ 2
ekko $*
$ bash ./manus.Sh Apple Banana
eple
banan
Apple Banana

Parameter $# er et tall med mengden posisjonsparametere som er gitt til et skript i dette tilfellet nedenfor, det er to argumenter som er bestått.

$ katteskript.sh
ekko $ 1
ekko $ 2
ekko $*
ekko $#
$ bash ./manus.Sh Apple Banana
eple
banan
Apple Banana
2

Tilde -utvidelse

Tilde -utvidelse sees ofte med brukernavn og hjemmekataloger, eksempler vises nedenfor.

Tilde -utvidelse for å få hjemmekatalogen til den nåværende brukeren, ved å bruke Just Tilde uten brukernavnet.

$ ekko $ bruker
rot
$ CD ~/
$ pwd
/rot

Se en spesifikk brukers hjemmekatalog, ikke den nåværende brukeren med Tilde og brukernavnet

$ cd ~ linuxhint
$ pwd
/Hjem/Linuxhint

Aritmetisk substitusjon

Aritmetisk substitusjon gjør at bash kan utføre matematiske operasjoner i skallet eller i et skript. Eksempler på vanlige bruksområder vises nedenfor.

Enkel aritmetisk substitusjon med $ og doble parenteser

$ ekko $ ((2 + 3))
5

Postøkrementoperatøren vil oppdatere verdien med en etter gjeldende kommando, merk at det er en tilsvarende Post Decrement som ikke er vist her.

$ X = 2
$ ekko $ ((x ++))
2
$ ekko $ x
3

Operatøren før økning vil oppdatere verdien med en rett før den gjeldende kommandoen, merk at det er en tilsvarende Pre Decrement -operatør som ikke er vist her.

$ X = 2
$ ekko $ ((++ x))
3
$ ekko $ x
3

Eksponentoperatøren kan heve et tall til en kraft eksponentielt

$ ekko $ ((5 ** 2))
25

Venstre bitvis skift; I dette tilfellet skifter bitene til desimal nummer 8 til venstre som i hovedsak multipliserer det med 2

$ ekko $ ((8<<1))
16

Høyre bitvis skift; I dette tilfellet skifter bitene til desimal nummer 8 til høyre som i hovedsak deler tallet med 2

$ ekko $ ((8 >> 1))
4

Bitvis og operatøren vil sammenligne tallene bit for bit, og resultatet vil være bitene som er alle satt.

$ ekko $ ((4 og 5))
4

Bitvis eller operatøren vil sammenligne tallene bit etter bit, og resultatene vil være bitene der en av inngangene har bit satt.

$ ekko $ ((4 | 9))
1. 3

Aritmetisk likhetsoperatør vil teste for sannhet og returnere 1 eller 0

$ ekko $ ((4 == 4))
1

Aritmetisk ulikhetsoperatør vil teste for ikke-likestilling og return 1 eller 0

$ ekko $ ((4 != 4))
0

Den betingede operatøren vil teste det første argumentet hvis det er sant, erstatt med det andre argumentet og hvis falsk erstatt med det tredje. I dette tilfellet tilsvarer 5 4+1 slik at den første betingede er sann og 9 blir returnert. 5 er ikke lik 4+2, så i den andre Echo 7 blir returnert.

$ ekko $ ((5 == 4+1 ? 9: 7))
9
$ ekko $ ((5 == 4+2 ? 9: 7))
7

Du kan bruke heksadesimale tall i aritmetiske utvidelser, i dette tilfellet tilsvarer 0xa 10 og 10+7 = 17.

$ ekko $ ((0xa + 7))
17

Ord splitting

Ved å bruke IFS -miljøvariabelen for å registrere en avgrenser, og ved å bruke lese- og readarray -kommandoene, kan vi analysere strenger i en rekke symboler og deretter telle symbolene og operere på dem. Eksempler vises nedenfor.
Bruk IFS -parameter som avgrenser, les symboler i en matrise splittet av IFS som er satt til et romkarakter, og skriv deretter ut symbolene en etter en

$ tekst = "Hello World"
$ Ifs = "
$ Les -A symboler <<< "$text"
$ ekko "Det er $ #tokens [*] ord i teksten.""

Det er to ord i teksten.

$ for i i "$ tokens [@]"; gjør ekko $ i; Ferdig
Hallo
Verden

Bruker ReadArray uten IFS og spesifiser avgrenser i ReadArray -kommandoen. Merk at dette bare er et eksempel der vi deler en katalogsti basert på skråstreken. I dette tilfellet har koden inkludert den tomme strengen før den første skråstreken som må justeres i en reell bruk, men vi viser bare hvordan du kan ringe Readarray for å dele en streng i symboler i en matrise med en avgrensning.

$ path = "/home/linuxhint/usr/local/bin"
$ readArray -D / -T Tokens <<< "$path"
ekko "Det er $ #tokens [*] ord i teksten.""

Det er 6 ord i teksten.

$ for i i "$ tokens [@]"; gjør ekko $ i; Ferdig
hjem
Linuxhint
usr
lokal
søppelkasse

Filnavnutvidelse

Når du ønsker å referere til en liste over filer eller kataloger i filsystemet, kan en bash -kommando eller bash -skript bruke filnavnutvidelse for å generere en liste over filer og kataloger fra enkle kommandoer. Eksempler vises nedenfor.

* Tegnet utvides til et jokertegn og henter alle matchende filer med resten av Wild Card String. Her henter vi alle filer som slutter .txt og gi dem inn i DU -kommandoen for å sjekke diskstørrelse.

$ berøring a.txt b.txt c.tekst
$ ECHO "Hello World"> Innhold.tekst
$ du *.tekst
0 a.tekst
0 f.tekst
0 c.tekst
4 Innhold.tekst

De ? Karakter vil bare samsvare med et enkelt tegn, ikke et uendelig antall tegn, og i dette eksemplet vil bare hente filnavn med et enkelt tegn etterfulgt av .tekst.

$ berøring a.txt b.txt c.tekst
$ ECHO "Hello World"> Innhold.tekst
$ du ?.tekst
0 a.tekst
0 f.tekst
0 c.tekst

Tegn i parentes utvides for å matche noen av karakterene. I dette eksemplet a.txt og c.TXT blir plukket opp av utvidelsen

$ berøring a.txt b.txt c.tekst
$ ECHO "Hello World"> Innhold.tekst
$ du [ac].tekst
0 a.tekst
0 c.tekst

Tegn i parentes kan være en rekke tegn, og vi ser her alle filer fra A til C -serien etterfulgt av .TXT -suffikset blir plukket opp

$ berøring a.txt b.txt c.tekst
$ ECHO "Hello World"> Innhold.tekst
$ du [a-c].tekst
0 a.tekst
0 f.tekst
0 c.tekst

Konklusjon

Vi har dekket mange typer skallutvidelser i denne artikkelen, og jeg håper de enkle eksemplene kan tjene som en kokebok for det som er mulig i bash for å gjøre deg mer produktiv med skallutvidelser. Som ytterligere referanser anbefaler jeg å lese Full Bash Manual, og også de mange gode artiklene på Nixcraft nettsted om bash -skripting inkludert skallutvidelser. Vi har andre artikler som kan være av interesse for deg på Linuxhint, inkludert: 30 bash -manuseksempler, bashs små store bokstaver, bash mønster matching og bash split strengeksempler. Vi har også et populært gratis 3 timers kurs på bash -programmering du kan finne på YouTube.