GNU/Linux >> Znalost Linux >  >> Linux

Bash skriptování (II)

Toto je druhý článek ze série zaměřené na skriptování Gnu Bash. V prvním článku o skriptování bash jsme právě vytvořili ten nejjednodušší skript:jednoduché příkazy, jeden po druhém. Také jsme viděli použití některých proměnných. Tento článek se bude zabývat řídicími strukturami bash.

Řídicí struktury

Jak jsem řekl v předchozím článku, lenost je klíčem k úspěchu. Pokud musím spustit nějaké příkazy, o chvíli později stejné příkazy ve stejném pořadí, až nastane potřetí, otevřu textový editor a vložím tyto příkazy, abych to uložil jako skript.

O několik dní později tento skript začíná růst, a to jak v rozšíření, tak ve složitosti. Potřebuji způsoby, jak řídit tok provádění, například:

  • pokud se něco stane, udělejte něco, nebo pokud se něco nestane, udělejte něco jiného;
  • když se něco děje, dělejte něco znovu a znovu nebo dělejte něco znovu a znovu;
  • nebo v závislosti na hodnotě proměnné nebo na tom, co se stalo, udělejte to či ono nebo ono,
  • atd

K tomu jsou určeny řídicí struktury bash (ve skutečnosti v bash nebo jakémkoli jiném programovacím jazyce). Nejprve však potřebujeme vědět o:

Stav ukončení

Z manuálové stránky bash:

«Stav ukončení provedeného příkazu je hodnota vrácená systémovým voláním waitpid nebo ekvivalentní funkcí. Stavy opuštění jsou mezi 0 a 255. (…) nulový stav ukončení označuje úspěch (nebo se rovná „pravdivému“). Nenulový stav ukončení označuje selhání (nebo se rovná 'false').(…. Například:) Pokud příkaz není nalezen, podřízený proces vytvořený k jeho provedení vrátí stav 127. Pokud je příkaz nalezen, ale není spustitelný, návratový stav je 126 ».

tl;dr:výstupní status 0 znamená true , úspěch; jakákoli jiná hodnota znamená false . Je důležité se to naučit, protože provádět správná/nepravdivá rozhodnutí znamená kontrolovat stav ukončení příkazu.

Bash ukládá stav ukončení posledního provedeného příkazu do $? proměnná.

if-then-else

Toto je pokud se něco stane (něco se stane znamená příkaz se stavem ukončení nula) udělejte něco nebo udělejte jinou věc. Syntaxe je:

if command
then
	command1
	command2
	...
else
	commandA
	commandB
	...
fi

Jak můžete vidět na snímku obrazovky, lze jej napsat na jeden řádek a každý příkaz oddělit středníkem:

příkaz
if command; then command1; command2;...; else commandA; commandB;...;fi

V závislosti na složitosti bloku if-then může být snazší nebo obtížnější přečíst styl „oneliner“.

Co když chcete spustit nějaký příkaz, když se něco stane, spusťte jiný příkaz pouze pokud něco jiného se děje? použijte klíčové slovo elif (else if):

if command
then
	command1
	command2
	...
elif other_command
	commandA
	commandB
	...
else
	another block of commands
fi

Blok if-then-else končí klíčovým slovem fi (pokud je to obráceně).

Porovnání řetězců a čísel

Pamatujete si proměnné? často se něco stane je, že v závislosti na hodnotě proměnné chceme spouštět nějaké příkazy nebo jiné.
Pro porovnání, zda se řetězec rovná nějakému slovu nebo číslu je nižší než jiné, použijeme příkaz test . Obecná syntaxe je:

test expression

Pokud výraz je vynecháno, považuje se za nepravdivé (stav ukončení> 0). Pokud výraz je to jen řetězec textu, to je pravda. To může být složité, například:

$ test false; echo $?
0

Netestujeme výstupní stav příkazu false (existuje příkaz false ), ale řetězec false proti ničemu. Dalším způsobem spuštění příkazu test je uzavření výrazu do hranatých závorek. Tento jiný způsob je snazší číst uvnitř bloku if-then-else.

operandy pravda, pokud
výraz pravda
! výraz false (neguje výraz)
výrazA -a výrazB A. oba výrazy jsou pravdivé
výrazA -o výrazB Nebo. jeden z výrazů je pravdivý
řetězec1 =řetězec2 oba řetězce jsou stejné
řetězec1 !=řetězec2 řetězce jsou různé
int1 -eq int2 celé číslo1 se rovná celému číslu2
int1-ge int2 int1>=int2
int1 -gt int2 int1> int2
int1 -le int2 int1 <=int2
int1 -lt int2 int1
int1 -ne int2 int1 se nerovná int2
-e soubor soubor existuje
adresář -d soubor existuje a je to adresář

Výrazů je více, právě ty považuji za důležitější. Přečtěte si manuálovou stránku pro test, abyste se naučili další výrazy.

Dávejte pozor, aby mezi oběma hranatými závorkami a výrazem byla mezera. Nyní můžeme pomocí testu něco udělat na základě hodnoty proměnné. Například:

případ

Když chceme otestovat proměnnou proti několika hodnotám, můžeme do našeho bloku if-then-else přidat více elif takto:

if [ $a = "value1" ]
then
	command1 for value1
	...
	commandN for value1
elif [ $a = "value2" ] 
then
	command1 for value2
	...
	commandN for value2
...
elif [ $a = "valueN" ] 
then
	command1 for valueN
	...
	commandN for valueN
else
	command1 for every other value
	...
	commandN for every other value
fi

Nebo můžeme nahradit příkazem case, který se snáze čte a píše:

case expression in
	value1)
		command1 for value1
		...
		commandN for value1
		;;
	value2)
		command1 for value2
		...
		commandN for value2
		;;
	...
	*)
		command1 for every other value
		...
		commandN for every other value
		;;
esac

Také méně stisknutí kláves, nezapomeňte být dostatečně líní, aby počítač pracoval za vás. Poslední hodnota * je výchozí případ, všechny ostatní hodnoty, které se předtím neshodovaly. Případ pozpátku, esac , je analogický s prohlášením fi. Pokud ;; Pokud je použit operátor, po první shodě vzoru se již nepokusí o žádné další shody. Pro otestování dalšího vzoru použijte ;;* operátor. Například:

dokdy a do

Zatímco je něco dělat znovu a znovu, zatímco se něco děje. A dokud je to stejné, ale negované (dělejte něco znovu a znovu, zatímco se něco neděje). Obecná syntaxe je:

while command
do
	command1
	command2
	...
	commandN
done

Chcete-li něco udělat, zatímco se neděje (tj. stav exist je jiný než 0), nahraďte while za dokud. Podívejte se na několik příkladů:

Všimněte si, že nevytvářeli stejný výstup. V bloku while, když $a dosáhne hodnoty 4, není více než 4, takže test je vyhodnocen jako false (a výstupní kód je> 0). Na bloku till, když $a dosáhne hodnoty 4, není větší než 4.

Hodiny ve vašem terminálu

Někdy testuji cronjob a to mě znervózňuje, dokud nebude proveden. Jako podmínku používám příkaz true (který, jak jste si možná mysleli, vytváří stav ukončení 0) a spouštím datum příkazu znovu a znovu:

while true
do
	date
	sleep 1
	clear
done

To by běželo déle, ale mohu přerušit pomocí ctrl-c.

pro-in -dělat

Tento druh smyčky iteruje přes poskytnutý seznam a přiřazuje každou položku do proměnné. Syntaxe:

for i in list of words
do
	command1
	...
	commandN
done

To je lépe vidět na příkladu:

Zůstaňte naladěni

Věci se stávají složitějšími, ale chceme, aby naše skripty přijaly určitá rozhodnutí, aby udělaly to či ono. Měl jsem se zabývat jinými tématy, ale tento článek o kontrolních strukturách bash se příliš rozrostl.

Na dalších se budu věnovat potrubí a přesměrování. Pravděpodobně se vrátím k těmto řídicím strukturám bash s příklady, něco jako použití výstupu příkazu ve smyčce for-in a podobně.


Linux
  1. Bash skriptování (I)

  2. příkaz pro export bash

  3. Spusťte příkaz bash na jenkins pipeline

  1. Vysvětlení příkazu Bash trap

  2. Bash čeká příkaz

  3. Příkaz „eval“ v Bash?

  1. Bash četl příkaz

  2. Bash Heredoc

  3. Příkaz zdroje Bash