GNU/Linux >> Znalost Linux >  >> Linux

Přidání argumentů a voleb do vašich Bash skriptů

Jedním z nejdůležitějších nástrojů pro většinu správců systému je automatizace. Píšeme a udržujeme skripty, abychom automatizovali běžné a časté úkoly, které musíme provádět.

Mám desítky scénářů – krátkých i dlouhých – které jsem během let napsal a upravil. Některé z mých nejužitečnějších skriptů byly pravidelné zálohování každé ráno, instalace aktualizovaných softwarových balíků s opravami a vylepšeními a upgrade z jedné verze Fedory na další. Před několika dny jsem upgradoval všechny své osobní hostitele a servery na Fedoru 34 pomocí poměrně jednoduchého skriptu.

[ Také by se vám mohlo líbit: Další hloupé Bashovy triky:Proměnné, hledání, deskriptory souborů a vzdálené operace ]

Dvě z nejběžnějších věcí, které dělám pro všechny své skripty, jsou vytváření funkce nápovědy a funkce, která zobrazuje prohlášení o licenci GPL3. Rád do svých skriptů zahrnuji podrobné nebo testovací režimy, které pomáhají při určování problémů. V některých skriptech také předávám hodnoty, jako je uživatelské jméno, verze Fedory, na kterou se má upgradovat, názvy souborů a další.

Jednou z metod, jak toho dosáhnout, je možnost používat poziční parametry – jinak známé jako argumenty – ke specifikaci dat, která mají být použita jako hodnoty pro proměnné ve skriptech. Dalším je použití opcí a opčních argumentů. Tento článek zkoumá tyto dvě metody pro získávání dat do skriptu a řízení cesty provádění skriptu.

Poziční parametry

Bash používá nástroj zvaný poziční parametry, který poskytuje prostředky pro zadávání dat do programu Bash, když je vyvolán z příkazového řádku. Existuje deset pozičních parametrů, které běží od $09 $ , i když existují způsoby, jak tento limit obejít.

Počínaje jednoduchým skriptem, který zobrazí zadané jméno na obrazovce. Vytvořte soubor s názvem script1.sh s následujícím obsahem a udělejte jej spustitelným.

#!/bin/bash
echo $0

Tento skript jsem umístil do svého ~/bin directory , kde mají být uloženy osobní spustitelné soubory, jako jsou skripty. Podívejte se na svou $PATH proměnná, která obsahuje /home/username/bin jako jedna složka. Pokud ~/bin adresář neexistuje, můžete jej vytvořit. Nebo můžete tento soubor jednoduše umístit kamkoli chcete a použít jej odtud.

Potom spusťte skript bez parametrů.

[student@testvm1 ~]$ script1.sh
/home/dboth/bin/script1.sh
[student@testvm1 ~]$

Výstupem tohoto skriptu je název skriptu. 0 $ Parametr je rezervován a předdefinován jako název běžícího skriptu a nelze jej použít pro žádný jiný účel. To může být užitečné ve skriptu, protože skriptu nemusíte předávat jeho vlastní název, pokud to vyžaduje.

Změňte tedy skript tak, aby používal $1 pro poziční proměnnou a spusťte ji znovu:

#!/bin/bash
echo $1

Spusťte jej znovu, tentokrát s jediným parametrem:

[student@testvm1 ~]$ script1.sh help
help
[student@testvm1 ~]$

Co se stane, pokud jsou parametrem dvě slova?

[student@testvm1 ~]$ script1.sh help me
help
[student@testvm1 ~]$

To jsou ve skutečnosti dva parametry, ale můžete to napravit pomocí uvozovek, jak je vidět zde:

[student@testvm1 ~]$ script1.sh "help me"
help me
[student@testvm1 ~]$

To může být užitečné tam, kde má být vstupem adresa ulice nebo něco s více slovy, jako je tento:

[student@testvm1 ~]$ script1.sh "80486 Intel St."
80486 Intel St.
[student@testvm1 ~]$

Jsou však chvíle, kdy potřebujete více parametrů, například se jmény nebo úplnými adresami.

Změňte program tak, aby vypadal takto:

#!/bin/bash
echo "Name: $1"
echo "Street: $2"
echo "City: $3"
echo "State/Province/Territory: $4"
echo "Zip/Postal code: $5"

A spusťte jej pomocí parametrů podle obrázku:

[student@testvm1 ~]$ script1.sh "David Both" "80486 Intel St." Raleigh NC XXXXX
Name: David Both
Street: 80486 Intel St.
City: Raleigh
State/Province/Territory: NC
Zip/Postal code: XXXXX

Samozřejmě existuje mnoho způsobů, jak použít poziční parametry, jakmile jsou přiřazeny hodnoty, ale tento malý program usnadňuje vidět, co se děje. Usnadňuje také bezpečné experimentování.

Zkuste dát parametry v jiném pořadí, abyste viděli, jak to funguje. Tyto parametry jsou poziční a to je klíčové hledisko. Musíte zvážit, kolik parametrů je potřeba, jak si je uživatel pamatuje a v jakém pořadí je umístit.

Potřebujete způsob, jak učinit pořadí parametrů irelevantním, a stále potřebujete způsob, jak upravit cestu provádění.

Možnosti

Tyto dvě věci můžete provést pomocí voleb příkazového řádku.

Zjistil jsem, že i jednoduché programy Bash by měly mít nějaký druh pomoci, i když je to docela základní. Mnoho z Bash shell programů, které píšu, se nepoužívá tak často, že mohu zapomenout přesnou syntaxi příkazu, který potřebuji zadat. Některé jsou prostě tak složité, že musím zkontrolovat požadované možnosti a argumenty, i když je často používám.

Díky vestavěné funkci nápovědy můžete tyto věci zobrazit, aniž byste se museli uchylovat ke kontrole samotného kódu. Součástí dokumentace programu je také dobrá a úplná nápověda.

O funkcích

Funkce shellu jsou seznamy příkazů programu Bash uložené v prostředí shellu a lze je spustit jako jakýkoli jiný příkaz zadáním jeho názvu na příkazový řádek. Funkce shellu mohou být také známé jako procedury nebo podprogramy v závislosti na dalším programovacím jazyku, který používáte.

Funkce jsou volány ve vašich skriptech nebo z CLI pomocí jejich názvů, stejně jako u jakéhokoli jiného příkazu. V programu CLI nebo skriptu se příkazy ve funkci provádějí při volání. Poté se sekvence toku programu vrátí k volající entitě a provede se další série programových příkazů v této entitě.

Syntaxe funkce je:

FunctionName(){příkazy programu}

Vytvořte jednoduchou funkci na CLI. Funkce je uložena v prostředí shellu pro instanci shellu, ve které je vytvořena. Vytvoříte funkci nazvanou hw , což znamená Ahoj světe . Zadejte následující kód na CLI a stiskněte Enter . Poté zadejte hw stejně jako jakýkoli jiný příkaz shellu.

[student@testvm1 ~]$ hw(){ echo "Hi there kiddo"; }
[student@testvm1 ~]$ hw
Hi there kiddo
[student@testvm1 ~]$

Dobře, takže jsem trochu unavený ze standardního "Ahoj světe!" Obvykle začínám s. Nyní uveďte všechny aktuálně definované funkce. Je jich hodně, tak jsem ukázal jen nový hw funkce. Při volání z příkazového řádku nebo v rámci programu vykonává funkce svou naprogramovanou úlohu. Poté se ukončí a vrátí řízení volající entitě, příkazovému řádku nebo dalšímu příkazu programu Bash ve skriptu po volajícím příkazu.

[student@testvm1 ~]$ declare -f | less
<snip>
hw ()
{
    echo "Hi there kiddo"
}
<snip>

Nyní tuto funkci odeberte, protože ji již nepotřebujete. Můžete to udělat pomocí unset příkaz, jako je tento:

[student@testvm1 ~]$ unset -f hw ; hw
bash: hw: command not found
[student@testvm1 ~]$

Skript hello.sh

Vytvořte nový skript shellu Bash, ~/bin/hello.sh a udělejte jej spustitelným. Přidejte následující obsah, který je pro začátek základní:

#!/bin/bash
echo "hello world!"

Spusťte jej, abyste ověřili, že vypisuje „hello world!“.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$

Já vím – nemůžu si pomoct, tak jsem se vrátil do „ahoj světe!“.

Vytvoření funkce nápovědy

Přidejte nápovědu funkce zobrazená níže ke kódu programu hello. Umístěte nápovědu funkce mezi dvěma příkazy, které již máte. Tato nápověda Funkce zobrazí krátký popis programu, syntaktický diagram a krátký popis každé dostupné možnosti. Do nápovědy můžete přidat také volání funkce k otestování a některé řádky komentářů, které poskytují vizuální vymezení mezi funkcemi a hlavní částí programu.

Program nyní vypadá takto.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################

Help
echo "Hello world!"

Možnosti popsané v této nápovědě Funkce může být typická v programech, které píšu, ačkoli v kódu zatím žádná není. Spusťte program a otestujte jej.

[student@testvm1 ~]$ hello.sh
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

Hello world!
[student@testvm1 ~]$

Protože jste nepřidali žádnou logiku pro zobrazení nápovědy, když ji chcete, program nápovědu vždy zobrazí. Víte však, že funkce funguje správně, takže můžete přidat určitou logiku pouze pro zobrazení nápovědy, když použijete -h možnost na příkazovém řádku vyvolání programu.

Možnosti manipulace

Schopnost skriptu Bash zpracovávat možnosti příkazového řádku, jako je -h zobrazení nápovědy vám poskytuje některé výkonné možnosti, jak program řídit a upravovat, co dělá. V případě vašeho -h chcete, aby program vytiskl text nápovědy k relaci terminálu a poté se ukončil bez spuštění zbytku programu. Schopnost zpracovávat možnosti zadané na příkazovém řádku lze přidat do skriptu Bash pomocí while ve spojení s getops a case příkazy.

getops příkaz přečte všechny možnosti zadané na příkazovém řádku a vytvoří seznam těchto možností. while příkaz prochází seznam možností nastavením proměnné $options pro každý v níže uvedeném kódu. case příkaz se používá k vyhodnocení každé volby v pořadí a provedení příkazů v odpovídající stanze. while příkaz bude pokračovat ve vyhodnocování seznamu voleb, dokud nebudou všechny zpracovány nebo dokud nenarazí na příkaz exit, který ukončí program.

Nezapomeňte odstranit nápovědu volání funkce těsně před echem „Ahoj světe!“ příkaz, takže hlavní část programu nyní vypadá takto.

############################################################
############################################################
# Main program                                             #
############################################################
############################################################
############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
   esac
done

echo "Hello world!"

Všimněte si dvojitého středníku na konci příkazu exit ve volbě case pro -h . To je vyžadováno pro každou možnost. Přidejte do tohoto příkazu case, abyste ohraničili konec každé možnosti.

Testování je nyní trochu složitější. Musíte svůj program otestovat s několika různými možnostmi – a žádnými možnostmi – abyste viděli, jak reaguje. Nejprve zkontrolujte, zda se bez možnosti vytiskne "Ahoj světe!" jak by mělo.

[student@testvm1 ~]$ hello.sh
Hello world!

To funguje, takže teď otestujte logiku, která zobrazuje text nápovědy.

[student@testvm1 ~]$ hello.sh -h
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|t|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

Funguje to podle očekávání, takže teď vyzkoušejte nějaké testování, abyste zjistili, co se stane, když zadáte nějaké neočekávané možnosti.

[student@testvm1 ~]$ hello.sh -x
Hello world!
[student@testvm1 ~]$ hello.sh -q
Hello world!
[student@testvm1 ~]$ hello.sh -lkjsahdf
Add a description of the script functions here.

Syntax: scriptTemplate [-g|h|t|v|V]
options:
g     Print the GPL license notification.
h     Print this Help.
v     Verbose mode.
V     Print software version and exit.

[student@testvm1 ~]$

Zpracování neplatných možností

Program pouze ignoruje možnosti, pro které jste nevytvořili konkrétní odpovědi, aniž by generoval jakékoli chyby. Ačkoli v posledním záznamu s -lkjsahdf možnosti, protože je v seznamu "h", program to rozpoznal a vytiskl text nápovědy. Testování ukázalo, že jedna věc, která chybí, je schopnost zpracovat nesprávný vstup a ukončit program, pokud je nějaký detekován.

Do příkazu case můžete přidat další stanzu case, která bude odpovídat jakékoli volbě, pro kterou neexistuje žádná explicitní shoda. Tento obecný případ bude odpovídat všemu, pro co jste nezadali konkrétní shodu. Případ výpis nyní vypadá takto.

while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done

Tento kousek kódu si zaslouží vysvětlení, jak to funguje. Vypadá to složitě, ale je to docela snadné pochopit. zatímco – hotovo struktura definuje smyčku, která se provede jednou pro každou možnost v volbě getopts struktura. ":h" string — který vyžaduje uvozovky — uvádí možné vstupní možnosti, které budou vyhodnoceny case – esac struktura. Každá uvedená volba musí mít v příkazu case odpovídající stanzu. V tomto případě jsou dvě. Jedním z nich je h) stanza, která volá proceduru nápovědy. Po dokončení procedury nápovědy se provádění vrátí k dalšímu příkazu programu, exit;; který opustí program bez provedení dalšího kódu, i když nějaký existuje. Smyčka zpracování voleb je také ukončena, takže nebudou zaškrtnuty žádné další volby.

Všimněte si univerzální shody \? jako poslední sloka v případovém prohlášení. Pokud jsou zadány nějaké volby, které nejsou rozpoznány, tato stanza vypíše krátkou chybovou zprávu a ukončí program.

Jakékoli další specifické případy musí předcházet konečnému souhrnu. Rád umisťuji sloky případů v abecedním pořadí, ale nastanou okolnosti, kdy chcete zajistit, aby byl konkrétní případ zpracován před některými jinými. Příkaz case je citlivý na posloupnost, takže si to uvědomte, když vytváříte ten svůj.

Poslední příkaz každé stanzy v konstrukci case musí končit dvojitým středníkem (;; ), který se používá k explicitnímu označení konce každé sloky. To umožňuje programátorům, kteří rádi používají explicitní středníky na konci každého příkazu namísto implicitních, aby v tom pokračovali pro každý příkaz v každé stanze case.

Otestujte program znovu pomocí stejných možností jako předtím a uvidíte, jak to nyní funguje.

Skript Bash nyní vypadá takto.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################
############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":h" option; do
   case $option in
      h) # display Help
         Help
         exit;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done


echo "hello world!"

Nezapomeňte tuto verzi svého programu velmi důkladně otestovat. Použijte náhodný vstup a uvidíte, co se stane. Měli byste také zkusit otestovat platné a neplatné možnosti bez použití pomlčky (- ) vpředu.

Použití možností pro zadávání dat

Nejprve přidejte proměnnou a inicializujte ji. Přidejte dva řádky zobrazené tučně do segmentu programu zobrazeného níže. Tím se inicializuje $Name proměnnou na "world" jako výchozí.

<snip>
############################################################
############################################################
# Main program                                             #
############################################################
############################################################

# Set variables
Name="world"

############################################################
# Process the input options. Add options as needed.        #
<snip>

Změňte poslední řádek programu, echo příkaz k tomuto.

echo "hello $Name!"

Přidejte logiku pro zadání názvu během okamžiku, ale nejprve znovu otestujte program. Výsledek by měl být úplně stejný jako předtím.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$
# Get the options
while getopts ":hn:" option; do
   case $option in
      h) # display Help
         Help
         exit;;
      n) # Enter a name
         Name=$OPTARG;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done

$OPTARG je vždy název proměnné použitý pro každý nový argument možnosti, bez ohledu na to, kolik jich je. Musíte přiřadit hodnotu v $OPTARG na název proměnné, který bude použit ve zbytku programu. Tato nová stanza nemá příkaz exit. To změní tok programu tak, že po zpracování všech platných voleb v příkazu case se provádění přesune k dalšímu příkazu po konstrukci případu.

Otestujte revidovaný program.

[dboth@david ~]$ hello.sh
hello world!
[dboth@david ~]$ hello.sh -n LinuxGeek46
hello LinuxGeek46!
[dboth@david ~]$ hello.sh -n "David Both"
hello David Both!
[dboth@david ~]$

Dokončený program vypadá takto.

#!/bin/bash
############################################################
# Help                                                     #
############################################################
Help()
{
   # Display Help
   echo "Add description of the script functions here."
   echo
   echo "Syntax: scriptTemplate [-g|h|v|V]"
   echo "options:"
   echo "g     Print the GPL license notification."
   echo "h     Print this Help."
   echo "v     Verbose mode."
   echo "V     Print software version and exit."
   echo
}

############################################################
############################################################
# Main program                                             #
############################################################
############################################################

# Set variables
Name="world"

############################################################
# Process the input options. Add options as needed.        #
############################################################
# Get the options
while getopts ":hn:" option; do
   case $option in
      h) # display Help
         Help
         exit;;
      n) # Enter a name
         Name=$OPTARG;;
     \?) # Invalid option
         echo "Error: Invalid option"
         exit;;
   esac
done


echo "hello $Name!"

Nezapomeňte otestovat nápovědu a to, jak program reaguje na neplatný vstup, abyste si ověřili, že nebyla ohrožena jeho schopnost zpracovat je. Pokud vše funguje, jak má, pak jste se úspěšně naučili používat volby a argumenty voleb.

[ Získejte tuto bezplatnou e-knihu:Správa clusterů Kubernetes pro figuríny. ]

Sbalit

V tomto článku jste použili poziční parametry k zadávání dat do programu Bash během vyvolání z příkazového řádku a použili jste možnosti k řízení toku programu a také k zadávání dat do programu. Přidali jste funkci nápovědy a možnost zpracovat možnosti příkazového řádku pro selektivní zobrazení nápovědy. A přidali jste volitelný argument, který umožňuje zadat název na příkazový řádek.

Tento malý testovací program je navržen tak, aby byl jednoduchý, takže s ním můžete snadno experimentovat a otestovat tuto metodu zadávání na vlastní kůži. Jako cvičení si upravte program tak, aby obsahoval křestní jméno a příjmení. Zkuste zadat možnosti jména a příjmení v opačném pořadí, abyste viděli, co se stane.

Zdroje

  • Jak programovat pomocí Bash:Syntaxe a nástroje
  • Jak programovat pomocí Bash:Logické operátory a rozšíření shellu
  • Jak programovat pomocí Bash:Loops

Linux
  1. V Bash, kdy alias, kdy skript a kdy napsat funkci?

  2. Předat argumenty příkazového řádku skriptu Bash?

  3. Variabilní rozsah pro skripty bash shell a funkce ve skriptu

  1. Jak používat vstupy ve skriptech shellu

  2. Nahrajte svůj terminál pomocí skriptu a scriptreplay

  3. Rozdíl mezi příkazy v bash skriptu a příkazy v terminálu

  1. Použít rozšíření .sh nebo .bash pro skripty Bash?

  2. Jak nastavit parametry, když Pipe Bash Script to Bash?

  3. Jak zvýraznit Bash skripty ve Vimu?