BASH Kouzla s příkazovou řádkou
Petr Koloros
Obsah ● ● ● ● ● ● ● ● ● ●
příkazová řádka proměnné prsaté závorky {hot! hot!} manipulace se soubory vstup, výstup, přesměrování hlídače regularní výrazy filtry skriptování pitfalls
Zvládáme příkazovou řádku ● ● ● ●
●
●
tab - doplňuje jména souborů, adresářů alt . - vypíše poslední argument Šipka nahoru - vyvolá poslední příkaz ctrl-r + počáteční písmena - vyhledávání v historii podle textu Ovládání jako Emacs nebo Vi (~/.inputrc, položka set editing-mode vi) Prompt se dá nastavit (proměná PS1)
Proměnné ● ●
Proměné se označují znakem $ na začátku Vypsání proměnné echo $promena
●
Ovšem u přiřazení hodnoty znak $ nesmí být promena=“hodnota“
Proměnné ● ●
● ● ● ● ● ●
Př. prompt se dá nastavit (proměná PS1) Konec zobrazení promptu označuje režim: #=root, $=user;předposl. znak ~=home Proměné lze vypsat příkazem set Další důležité proměnné prostředí: PATH (kde hledat spustitelné soubory) HOME (domovský adresář) USER, UID (aktuální uživatel) LANG, LC_.. (jazyk, který mají programy používat)
Kouzla s proměnnými ● ● ● ● ● ● ● ● ●
Magický mód umožní zejména prsaté závorky Proměnná „a“ a má hodnotu „soubor_1.jpg“ ${a%jpg} – vypíše soubor_1 ${a/1/jedna} – vypíše soubor_jedna.jpg ${a#soubor} – vypíše _1.jpg ${a#*bor} – to samé ${#a} – 12 (délka hodnoty) ${a:3:4} – bor_ (substring) ${a:-default_file} – vypíše soubor_1.jpg, ale když proměná a není nastavená, vypíše default_file.
Příkazy pro práci se soubory ● ● ● ● ●
ls – výpis souborů (LiSt) cd – změna adresáře (Change Dir) cp – kopírování (CoPy) mv – přesun (MoVe) pwd – zobrazení názvu aktuálního adresáře
Zápis příkazů Sekvenčně (oddělené středníkem): prikaz1 argument; prikaz2; prikaz3 argument argument; prikaz4 V blocích (oddělené enterem): prikaz1 argument prikaz2 prikaz3 argument argument prikaz4
Zápis příkazů Pokud chcete příkaz provést a pak pracovat s výsledkem, použijte zpětné apostrofy: a=`ls -1` echo $a Pokud chcete vykonat sadu příkazů, jako jeden příkaz, uzavřete je do závorek: (příkaz1; příkaz2; příkaz 3)
Práce se soubory * - nahrazuje blíže neurčený počet blíže neurčených znaků Příklad: echo *JPG
For cyklus Pro hromadné provedení příkazu použijeme „smyčku“ for. obecně: for proměná in list; do tělo cyklu; done konkrétně: for a in *JPG; do echo $a; done vypíše všechny soubory s příponou JPG
Práce se soubory Využijeme předchozích znalostí: for a in *JPG; do mv $a ${a%JPG}jpg; done
mv – přesun souboru ${a%JPG}jpg – odebere příponu JPG a přidá jpg: $a s1.JPG s2.JPG s3.JPG
${a%JPG} s1. s2. s3.
Práce se soubory dry run: for a in *JPG; do echo mv $a ${a%JPG}jpg; done mv s1.JPG s1.jpg mv s2.JPG s2.jpg mv s3.JPG s3.jpg Na ostro: for a in *JPG; do echo mv $a ${a%JPG}jpg; done | sh
Vstup a výstup Každý program má: standardní vstup, označuje se 0 standardní výstup, označuje se 1 standardní chybový výstup, označuje se 2
Přesměrování „> soubor“
přesměruje výstup do souboru
„< soubor“
použije vstup ze souboru
„|“ (roura)
vezme výsledek předchozího příkazu a pošle ho jako vstup do dalšího příkazu.
„n>&y“
připojí výstup n k výstupu y
Vstup a výstup - příklady přesměrování výstupu do souboru echo „ahoj“ > soubor přesměrování chybových hlášek do souboru ls nenisoubor 2> chyby přesměrování všeho do souboru ./program > soubor 2>&1 2>&1 připojí chybový výstup do standardního výstupu
Další cykly While: while podmínka; do tělo; done nevýhoda – proměná se někdy neprojeví mimo cyklus (např. b=“nic“;cat soubor | while read a; do b=$a; done; echo $b) For (jako v jazyce „C“): for (( expr1 ; expr2 ; expr3 )) ; do tělo ; done Xargs: např. echo „1 2 3“ | xargs -n1 příkaz provede příkaz 1; příkaz 2; příkaz 3
Hlídače Hlídač monitoruje nějaký stav a dá vědět, až to začne být zajímavé. Ingredience: ● ● ● ●
zjištění stavu podmínky cyklus (for, while, ..) nečinost po nějakou dobu
Podmínky If podmínka; then tělo; [else další tělo ]; fi podmínka: ● ● ●
výsledek příkazu (pravdivá podmínka pokud vše v pořádku) výraz (nutno zapsat s užitím [ ]) speciální příkazy (true, false), mají pokaždé stejnou hodnotu
Příklad: if [ $a -eq 1 ]; then echo „jedna“; fi
Výrazy v [] a operátory Výrazy v [] mají svá úskalí, např. operátory porovnávání:
Podmínka rovná se větší menší větší než menší než
Práce s textem Práce s čísly == -eq > -gt < -lt >= -ge <= -le
Výrazy v [] a operátory Existují i podmínky s jedním argumentem:
Podmínka Práce s textem existuje soubor -f jméno existuje spustitelný soubor -x jméno existuje adresář -d jméno řetězec má nulovou délku -z řetezec
Výrazy a logické operátory „||“ - or –
pokud alespoň jeden z výrazů je pravda, výsledek je pravda „&&“ - and – pokud jsou všechny výrazy pravda, výsledek je pravda Užití jako rozhodovacího elementu při sekvenčním pouštění příkazů: příkaz1 && příkaz2 – druhý se provede jen pokud první je pravda příkaz1 || příkaz2 – druhý se neprovede pokud první je pravda
Další příkazy cat – vypíše vstup na výstup nebo soubor na výstup cut – vypíše části textu oddělené oddělovačem (oddělovač -d znak, pole -f n nebo -f n-m) grep – vypíše řádky, které souhlasí zadanému regulárnímu výrazu. Pracuje se souborem nebo std. vstupem. Př.: cat soubor - vypíše soubor na obrazovku cut -d“:“ -f 2 – vypíše políčko po druhém dělítku grep „^eth1“ soubor – vypíše řádky souboru začínající slovem eth1
Hlídač Příkaz pro nečinnost po dobu n sekund: sleep n while true; do echo $a; sleep 1; a=$((a+1)); done a=$((a+1)) – zvýší proměnnou a o jedničku (ještě možno :let a=a+1) Cyklus vypisuje každou sekundu číslo o jedničku větší než předtím. Cyklus je nekonečný a zastaví se CTRL-C.
Hlídač Příkaz cat vypíše obsah souboru na std. výstup (popř vypíše std. vstup, pokud není zadán argument) Výpis vstupního toku na síťové kartě: while true; do a=`cat dev|grep eth0| cut -d":" -f2|cut -f1 -d" "`; echo $((a-b)); b=$a; sleep 1;done
Hlídač Příkaz cat vypíše obsah souboru na std. výstup (popř vypíše std. vstup, pokud není zadán argument). Výpis toku na síťové kartě a zastavení aplikace, pokud rychlost v přijímacím směru překoná 10000 bytů/s: b=`cat dev|grep eth0| cut -d":" -f2|cut -f1 -d" "`; while true; do a=`cat dev|grep eth0| cut -d":" -f2|cut -f1 -d" "`; c=$((a-b)); if [ $c -gt 10000 ]; then break; fi; echo $c; b=$a; sleep 1;done && killall app_name Lze nahradit například příkazem, který pošle SMS nebo mail (příklad echo „telo mailu“ | mail mailova@adresa -s subject)
Regulární výrazy . - libovolný znak ? - výskyt předchozího znaku 0-1 krát * - výskyt předchozího znaku 0 a vícekrát + - výskyt předchozího znaku 1 a vícekrát () - grouping, často lze se odvolávat na tuto část výrazu [znaky] - množina znaků ^ - začátek $ - konec [^znaky] - ^ značí které znaky se v dané části nesmí vyskytovat Př.: ^[0-9,a-z]$ - výraz vyhovuje textu,který obsahuje jen písmena a-z a čísla 0-9 (např. ab9cd, 1234abbba)
Další příkazy uniq – vypíše každou položku pouze jednou sort – setřídí seznam (možno numericky, podle n-tého pole) wc – word count – spočítá slova, písmena, řádky Př.: cat soubor |sort|uniq - vypíše unikátní řádky ze souboru wc -l soubor – spočítá, kolik řádek má soubor
Programy usnadnující práci awk – samostatný „jazyk“, vhodný pro ● práci s čísly ● nahrazování ● hledání podle regulárních výrazů sed – stream editor, vhodný pro ● nahrazování tr – translate or delete Př.: awk '{ print $5 }' soubor - vypíše pátý sloupec ze souboru (sloupce jsou odděleny jednou nebo více mezerami, tabulátory, etc.)
Příklady awk '{ print $5 }' soubor - vypíše pátý sloupec ze souboru (sloupce jsou odděleny jednou nebo více mezerami, tabulátory, etc.) sed 's/name/jmeno/g' soubor – nahradí výskyt slova „name“ slovem „jmeno“ cat soubor | tr '\012' ' ' – nahradí konce řádek mezerou
Filtry Vypíše počet unikátních adres, ze kterých byl požadována určitá webová stránka:
grep alpy /opt/apache/logs/access_log | awk '{ print $1 }'|sort|uniq|wc -l Program pro stahnutí webové stránky: wget http://sut.sh.cvut.cz -O Parametr, který říká, kam se má uložit soubor Značí výstup do konzole
Filtry Stahnutí hodnoty aktuální teploty z webové stránky: http://teplomer.sh.cvut.cz
wget http://teplomer.sh.cvut.cz/ -O 2>/dev/null | grep "teplota:"|cut -d" " -f3|cut -d "<" -f1
Filtry Výpis odkazů z webové stránky: http://teplomer.sh.cvut.cz
wget http://teplomer.sh.cvut.cz/ -O -|grep href|grep http|sed 's/.*="\(.*\)".*/\1/g' Regulární výraz To, co je uvnitř \( \) se objeví v „proměnné“ \1
Skriptování Skript je soubor. Můžeme specifikovat příkazový interpret na začátku. Pokud tak neučiníme, spustí se aktuální příkazový interpret (bash?): #! /bin/bash echo “ahoj svete“ Dál zapisujeme řádky a oddělujeme enterem (je to přehlednější, než středníky). Intrepret pro jiné jazyky specifikujeme podobně: #! /usr/bin/perl nebo #! /usr/bin/python
Skriptování – funkce v BASHi Bash umí i funkce: funkce() { tělo } funkce se volá: funkce parametr1 parametr2 parametr3 Na parametry se lze odvolat uvnitř fce pomocí proměnných: $1, $2, ..
Skriptování – parametry z řádky Každý skript dostane všechny parametry v proměnných: $1, $2, .. cat skript echo „parametr \$1 je $1“ ./skript ahoj svete parametr 1 je svete Další proměné označují počet parametrů: $# - počet parametrů $@ - všechny parametry $0 – název skriptu
BASH - pitfalls Vyhodnocování výrazů Výrazy, které bash „překládá“ nutno zapsat jako \výraz př. echo $a echo \$a
- vypíše obsah proměnné „a“ - vypíše text „$a“
Mezery nutno také psát jako „slovo\ slovo“ nebo v uvozovkách Výrazy v podmínkách a mezery: U podmínek v „[ výraz ]“ musí být mezera mezi závorkami a výrazem
BASH - pitfalls Operátory && a || Pokud použijete and nebo or operátor, provede se pouze mezi dvěma argumenty. Př.: false && echo „ahoj“; echo „svete“ svete když použijete () pro seskupení více příkazů: false && (echo „ahoj“; echo „svete“) Nevypíše se nic, protože se obě echa chovají jako jeden příkaz
BASH - pitfalls Přesměrování a sloučení Pokud použijete např. 2>&1 a zároveň chcete výstup směrovat do souboru, musíte nejprve směrovat do souboru a pak slučovat: Př.: program >soubor 2>&1 Hodí se do cronu Pokud si přidáte spuštění příkazů do cronu a výstup přesměrujete do souboru a nastane chyba, pošle se vám automaticky mailem (jako každý výpis programu, který byl puštěn pomocí cronu. Pokud nechcete aby vám program něco vypisoval, přesměrujte i chybový výstup.
AWK vychytávky Awk a regulární výrazy: Awk umí regulární výrazy a vkládají se do mezi // Příklad: Vypis řádek začínající slovem ahoj: awk '/^ahoj/' soubor Vypis řádek od nalezení trojciferného čísla začínajícího trojkou až do čísla začínajícího čtyřkou: awk '/3../,/4../' soubor
SED pitfalls Na příkladu jsme si ukázali, jak dostat odkazy ze stránky. Text:
stoupa jsme sedem: sed 's/.*="\(.*\)".*/\1/g' přefiltrovali na http://stoupa.sh.cvut.cz Kdyby tam bylo ale:
stoupa“text“ dostali bychom: http://stoupa.sh.cvut.cz">stoupa"text Takže správně by měl sed být: cat s | sed 's/.*href="\([^<]*\)".*/\1/g'
Bonus – zmenšení fotek podle exifu Exif je informace, ze které lze zjistit natočení fotky (pokut to fotoaparát podporuje). Tento příklad zmenšuje fotky do rozlišení s výškou 768 pixelů a respektuje natočení: for a in *jpg; do if exif $a|grep Orientation|head -1|grep bottom >/dev/null; then res="768x"; else res="x768"; fi; echo convert \-resize $res $a resized/$a; done|sh
Pochopení řešení nechám na vás jako samostudium.
Odkazy SED – http://www.grymoire.com/Unix/Sed.html man sed AWK man awk BASH man bash http://aa.vslib.cz/silk/skola/prs/klavesy.html http://aa.vslib.cz/silk/skola/prs/prehled.html http://www.tldp.org/LDP/abs/html/ Nejlepší je učit se ze skriptu druhých. Naučíte se rychle techniky a vychytávky.