GNU/Linux >> Znalost Linux >  >> Linux

Úvod do programování Linux Bash:5 tipů pro smyčky „for“.

Každý správce systému má pravděpodobně nějakou dovednost, kterou se za ta léta naučil, na kterou může ukázat a říct:"To změnilo můj svět." Ta dovednost, nebo ten kousek informací nebo ta technika prostě změnily, jak věci dělám. Pro mnohé z nás je to zacyklení v Bash. Existují další přístupy k automatizaci, které jsou jistě robustnější nebo škálovatelnější. Většina z nich se nevyrovná jednoduchosti a snadné použitelnosti for smyčka.

Pokud chcete automatizovat konfiguraci tisíců systémů, měli byste pravděpodobně použít Ansible. Pokud se však pokoušíte přejmenovat tisíc souborů nebo provést stejný příkaz několikrát, pak for smyčka je rozhodně tím správným nástrojem pro tuto práci.

[ Také by se vám mohlo líbit: Ovládání smyček pomocí šablon Jinja v Ansible ]

Pokud již máte zkušenosti s programováním nebo skriptováním, pravděpodobně víte, k čemu for smyčky ano. Pokud nejste, pokusím se to pro vás rozebrat v jednoduché angličtině.

Základní koncept je:PRO danou sadu položek, DO věc.

Daná sada položek může být doslovná sada objektů nebo cokoli, co může Bash extrapolovat na seznam. Například text vytažený ze souboru, výstup jiného příkazu Bash nebo parametry předávané přes příkazový řádek. Převod této struktury smyčky na Bash skript je také triviální. V tomto článku vám ukážeme několik příkladů for smyčka může způsobit, že budete vypadat jako hrdina příkazového řádku, a poté vezmeme některé z těchto příkladů a vložíme je do strukturovanějšího skriptu Bash.

Základní struktura cyklu for

Nejprve si promluvme o základní struktuře for smyčka, a pak se pustíme do několika příkladů.

Základní syntaxe for smyčka je:

for <variable name> in <a list of items>;do <some command> $<variable name>;done;

Název proměnné bude proměnná, kterou zadáte v do a bude obsahovat položku ve smyčce, ve které se nacházíte.

seznam položek může být cokoli, co vrátí seznam oddělený mezerou nebo novým řádkem.

Zde je příklad:

$ for name in joey suzy bobby;do echo $name;done

Je to tak jednoduché, jak to jen jde, a neděje se toho moc, ale pomůže vám to začít. Proměnná $name bude obsahovat položku v seznamu, se kterou smyčka aktuálně pracuje, a jakmile příkaz (nebo příkazy) v do provedete, smyčka se přesune na další položku. Můžete také provést více než jednu akci na smyčku. Cokoli mezi do a done bude popraven. Nové příkazy potřebují pouze ; vymezující je.

$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby

Teď něco skutečného příklady.

Přejmenování souborů

Tato smyčka přebírá výstup příkazu Bash ls *.pdf a provede akci s každým vráceným názvem souboru. V tomto případě přidáváme dnešní datum na konec názvu souboru (ale před příponu souboru).

for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done

Pro ilustraci spusťte tuto smyčku v adresáři obsahujícím tyto soubory:

file1.pdf
file2.pdf
...
fileN.pdf

Soubory budou přejmenovány takto:

file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf

V adresáři se stovkami souborů vám tato smyčka ušetří značné množství času při přejmenování všech z nich.

Extrapolace seznamů položek

Představte si, že máte soubor, který chcete scp na několik serverů. Pamatujte, že můžete kombinovat for smyčka s dalšími funkcemi Bash, jako je expanze shellu, která umožňuje Bash rozšířit seznam položek, které jsou v sérii. To může fungovat pro písmena a čísla. Například:

$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10

Za předpokladu, že jsou vaše servery pojmenovány podle nějakého vzoru, jako je web0 , web1 , web2 , web3 , můžete nechat Bash iterovat řadu čísel takto:

$ for i in web{0..10};do scp somefile.txt ${i}:;done;

Toto bude iterováno přes web0 , web1 , web2 , web3 , a tak dále, provedením vašeho příkazu pro každou položku.

Můžete také definovat několik iterací. Například:

$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c

Můžete také kombinovat iterace. Představte si, že máte dvě datová centra, jedno ve Spojených státech a další v Kanadě, a konvence pojmenování serveru určuje, ve kterém datovém centru žil pár serverů HA. Například web-us-0 by byl prvním webovým serverem v datovém centru v USA, zatímco web-ca-0 by byly webové 0 protějšek v datovém centru CA. Chcete-li provést něco na obou systémech, můžete použít sekvenci jako je tato:

$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3

V případě, že názvy vašich serverů nelze snadno iterovat, můžete poskytnout seznam názvů do for smyčka:

$ cat somelist
first_item
middle_things
foo
bar
baz
last_item

$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item

Vnoření

Některé z těchto nápadů můžete také kombinovat pro složitější případy použití. Představte si například, že chcete na své webové servery zkopírovat seznam souborů, které se řídí konvencí číslování, kterou jste použili v předchozím příkladu.

Můžete toho dosáhnout opakováním druhého seznamu založeného na prvním seznamu prostřednictvím vnořených smyček. To je trochu těžké sledovat, když to děláte jako jednovrstvé, ale určitě to lze udělat. Vaše vnořené for smyčka se provede při každé iteraci nadřazeného for smyčka. Nezapomeňte zadat různé názvy proměnných pro každou smyčku.

Chcete-li zkopírovat seznam souborů soubor1.txt, soubor2.txt, a file3.txt k webovým serverům použijte tuto vnořenou smyčku:

$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3

Další přejmenování kreativ

Mohou existovat i jiné způsoby, jak toho dosáhnout, ale pamatujte, že toto je pouze příklad toho, co můžete proveďte pomocí for smyčka. Co když máte horu souborů pojmenovaných něco jako FILE002.txt? a chcete nahradit FILE s něčím jako TEXT . Pamatujte, že kromě samotného Bash máte k dispozici také další open source nástroje, jako je sed , grep , a více. Tyto nástroje můžete kombinovat s for smyčka, jako je tato:

$ ls FILE*.txt
FILE0.txt  FILE10.txt  FILE1.txt  FILE2.txt  FILE3.txt  FILE4.txt  FILE5.txt  FILE6.txt  FILE7.txt  FILE8.txt  FILE9.txt

$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done

$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory

$ ls TEXT*.txt
TEXT0.txt  TEXT10.txt  TEXT1.txt  TEXT2.txt  TEXT3.txt  TEXT4.txt  TEXT5.txt  TEXT6.txt  TEXT7.txt  TEXT8.txt  TEXT9.txt

Přidání smyčky for do skriptu Bash

Spuštění for smyčky přímo na příkazovém řádku je skvělé a ušetří vám to značné množství času na některé úkoly. Kromě toho můžete zahrnout for smyčky jako součást vašich Bash skriptů pro vyšší výkon, čitelnost a flexibilitu.

Příklad vnořené smyčky můžete například přidat do skriptu Bash, abyste zlepšili jeho čitelnost, takto:

$ vim copy_web_files.sh
# !/bin/bash

for i in file{1..3};do
  for x in web{0..3};do
    echo "Copying $i to server $x"
    scp $i $x
  done
done

Když uložíte a spustíte tento skript, výsledek je stejný jako při spuštění výše uvedeného příkladu vnořené smyčky, ale je čitelnější a navíc se snáze mění a udržuje.

$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3

Můžete také zvýšit flexibilitu a opětovnou použitelnost vašeho for smyčky jejich zahrnutím do skriptů Bash, které umožňují zadávání parametrů. Chcete-li například přejmenovat soubory jako v příkladu Další kreativní přejmenování výše umožňuje uživateli zadat příponu názvu, použijte tento skript:

$ vim rename_files.sh
# !/bin/bash

source_prefix=$1
suffix=$2
destination_prefix=$3

for i in $(ls ${source_prefix}*.${suffix});do
  mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done

V tomto skriptu uživatel zadá předponu zdrojového souboru jako první parametr, příponu souboru jako druhý a novou předponu jako třetí parametr. Chcete-li například přejmenovat všechny soubory začínající FILE , typu .txt na TEXT , spusťte skript takto:

$ ls FILE*.txt
FILE0.txt  FILE10.txt  FILE1.txt  FILE2.txt  FILE3.txt  FILE4.txt  FILE5.txt  FILE6.txt  FILE7.txt  FILE8.txt  FILE9.txt

$ bash rename_files.sh FILE txt TEXT

$ ls TEXT*.txt
TEXT0.txt  TEXT10.txt  TEXT1.txt  TEXT2.txt  TEXT3.txt  TEXT4.txt  TEXT5.txt  TEXT6.txt  TEXT7.txt  TEXT8.txt  TEXT9.txt

Toto je podobné původnímu příkladu, ale nyní mohou vaši uživatelé zadat další parametry pro změnu chování skriptu. Chcete-li například přejmenovat všechny soubory, které nyní začínají TEXT na NOVÉ , použijte následující:

$ bash rename_files.sh TEXT txt NEW

$ ls NEW*.txt
NEW0.txt  NEW10.txt  NEW1.txt  NEW2.txt  NEW3.txt  NEW4.txt  NEW5.txt  NEW6.txt  NEW7.txt  NEW8.txt  NEW9.txt

[ Bezplatný kurz pro vás:Technický přehled virtualizace a migrace infrastruktury. ] 

Závěr

Doufejme, že tyto příklady demonstrovaly sílu for smyčka na příkazovém řádku Bash. Pomocí smyček můžete skutečně ušetřit spoustu času a provádět úkoly způsobem, který je méně náchylný k chybám. Jen buď opatrný. Vaše smyčky udělají to, o co je požádáte, i když je požádáte, aby udělaly něco destruktivního náhodou, jako je vytvoření (nebo smazání) logických svazků nebo virtuálních disků.

Doufáme, že Bash for smyčky změní váš svět stejně, jako změnily náš.


Linux
  1. Programovací jazyk C - Úvod

  2. Skriptování v Linuxu:3 postupy pro smyčky while v Bash

  3. 12 Bash pro příklady smyček pro vaše skriptování prostředí Linux

  1. Jak napsat smyčku v Bash

  2. Zazimujte výzvu Bash v Linuxu

  3. Převaděč verzí PDF pro Linux

  1. Úvod do Nmap na Kali Linuxu

  2. Analýza historie Bash v Linuxu

  3. Linux bash. pro smyčku a funkci, pro sčítání čísel