Uvod v programiranje v BASH - HOW-TO Mike G mikkey at dynamo.com.ar Èet Jul 27 09:36:18 ART 2000 _________________________________________________________________ Ta spis vam bo pomagal pri va¹ih zaèetkih pisanja osnovnih in nekoliko zahtevnej¹ih lupinskih skriptov. Njegov namen ni biti vsemogoèen vodnik (glej naslov). Sam NISEM nikakr¹en izvedenec v programiranju v lupini in sem ta spis napisal zato, ker se bom pri tem veliko nauèil, poleg tega pa bo morda koristilo tudi drugim ljudem. Vsak odziv je dobrodo¹el, ¹e posebno v obliki popravkov :) _________________________________________________________________ Kazalo 1. Uvod * 1.1 Kje dobiti najnovej¹o razlièico? * 1.2 Potrebno znanje * 1.3 Uporaba tega spisa 2. Zelo preprosti skripti * 2.1 Tradicionalen skript 'Hello World' * 2.2 Zelo preprost skript za varnostno kopijo 3. Vse o preusmerjanju * 3.1 Teorija in hitri napotki * 3.2 Primer: stdout v datoteko * 3.3 Primer: stderr v datoteko * 3.4 Primer stdout v stderr * 3.5 Primer: stderr v stdout * 3.6 Primer: stderr in stdout v datoteko 4. Cevovodi * 4.1 Kaj so cevovodi in zakaj bi jih hoteli uporabljati * 4.2 Primer: preprost cevovod s programom sed * 4.3 Primer: alternativa ukazu 'ls -l *.txt' 5. Spremenljivke * 5.1 Primer: Hello World! z uporabo spremenljivk * 5.2 Primer: Zelo preprost skript za varnostno kopijo (nekoliko bolj¹i) * 5.3 Lokalne spremenljivke 6. Pogojni stavki * 6.1 Teorija * 6.2 Primer: Osnovni pogojni stavek if .. then * 6.3 Primer: Osnovni pogojni stavek if .. then ... else * 6.4 Primer: pogojni stavki s spremenljivkami 7. Zanke for, while in until * 7.1 Primer zanke for * 7.2 Zanka for kot v programskem jeziku C * 7.3 Primer zanke while * 7.4 Primer zanke until 8. Funkcije * 8.1 Primer funkcij * 8.2 Primer funkcije s parametri 9. Uporabni¹ki vmesniki * 9.1 Uporaba select za ustvarjanje preprostih menijev * 9.2 Uporaba parametrov z ukazne vrstice 10. Razno * 10.1 Branje uporabnikovega vnosa z read * 10.2 Raèunanje * 10.3 Iskanje bash * 10.4 Vrnjena vrednost programa * 10.5 Zajemanje izhoda ukaza * 10.6 Veè izvornih datotek 11. Tabele * 11.1 Primerjalni operatorji za nize * 11.2 Primerjave nizov * 11.3 Aritmetièni operatorji * 11.4 Primerjalni aritmetièni operatorji * 11.5 Priroèni ukazi 12. ©e veè skriptov * 12.1 Izvajanje ukaza na vseh datotekah v imeniku. * 12.2 Primer: Preprost skript za varnostno kopijo (¹e nekoliko bolj¹i) * 12.3 Preimenovalnik datotek * 12.4 Preimenovalnik datotek (preprost) 13. Ko gre kaj narobe (razhro¹èevanje) * 13.1 Naèini klicanja BASH 14. O tem spisu * 14.1 (brez) jamèenja * 14.2 Prevodi * 14.3 Zahvale * 14.4 Zgodovina * 14.5 ©e veè virov _________________________________________________________________ 1. Uvod 1.1 Kje dobiti najnovej¹o razlièico? http://www.linuxdoc.org/HOWTO/Bash-Prog-Intro-HOWTO.html 1.2 Potrebno znanje Dobro poznavanje ukazne vrstice GNU/Linux ter osnovnih pojmov programiranja je dobrodo¹lo. Èeprav tole ni uvod v programiranje samo, pojasnjuje (oziroma si vsaj prizadeva pojasniti) mnogo osnovnih pojmov. 1.3 Uporaba tega spisa Ta spis vam bo pri¹el prav v sledeèih primerih: * Imate nekaj predstav o programiranju in bi radi zaèeli pisati lupinske skripte. * Imate nejasno predstavo o programiranju in potrebujete nekaj napotkov. * ®elite videti nekaj lupinskih skriptov ter komentarjev, da boste lahko zaèeli pisati svoje lastne. * Selite se iz DOS/Windows (oziroma ste se pravkar preselili) in bi ¾eleli narediti "paketne" procese. * Ste popoln raèunalni¹ki navdu¹enec in preberete vsak how-to, ki vam pride na pot. 2. Zelo preprosti skripti Ta HOW-TO vam bo dal nekaj namigov o lupinskih skriptih, ki bodo moèno oprti na primere. V tem delu boste na¹li nekaj kratkih skriptov, ki vam bodo pomagali razumeti razliène tehnike. 2.1 Tradicionalen skript 'Hello World' #!/bin/bash echo Hello World Ta skript ima samo dve vrstici. Prva pove sistemu, kateri program naj uporabi pri zaganjanju datoteke. Druga vrstica vsebuje edin ukaz, ki ga skript izvede, in ta izpi¹e 'Hello World' na terminal. Èe dobite nekaj kot ./hello.sh: Command not found., je verjetno napaèna prva vrstica, '#!/bin/bash' - da bi ugotovili pravilno pot do bash izvedite 'whereis bash' ali poglejte v poglavje 'Iskanje bash'. 2.2 Zelo preprost skript za varnostno kopijo #!/bin/bash tar -cZf /var/moja-varnostna-kopija.tgz /home/jaz/ V tem skriptu namesto izpisovanja sporoèila na terminal naredimo arhiv uporabnikovega domaèega imenika. Ne uporabljajte tega skripta - obstaja tudi mnogo bolj¹i, ki bo predstavljen kasneje. 3. Vse o preusmerjanju 3.1 Teorija in hitri napotki Obstajajo trije opisniki datoteke - stdin (standardni vhod), stdout (standardni izhod) ter stderr (standardni izhod za napake). V osnovi lahko: 1. preusmerite stdout v datoteko 2. preusmerite stderr v datoteko 3. preusmerite stdout v stderr 4. preusmerite stderr v stdout 5. preusmerite stderr in stdout v datoteko 6. preusmerite stderr in stdout v stdout 7. preusmerite stderr in stdout v stderr 1 'predstavlja' stdout in 2 stderr. Majhno pojasnilo za predstavo o teh stvareh: z ukazom less si lahko ogledate tako stdout (ki bo ostal v medpomnilniku) kot stderr, ki se bo izpisal na zaslon, vendar bo izginil, ko se boste posku¹ali premikati po medpomnilniku. 3.2 Primer: stdout v datoteko To bo preusmerilo izhodni tok programa v datoteko. ls -l > ls-l.txt V tem primeru bo ustvarjena datoteka z imenom 'ls-l.txt', ki bo vsebovala tisto, kar bi se sicer izpisalo na zaslon, ko bi pognali ukaz 'ls -l'. 3.3 Primer: stderr v datoteko Takole lahko standardni izhod za napake preusmerimo v datoteko. grep da * 2> grep-napake.txt Ustvarjena bo datoteka z imenom 'grep-napake.txt', v njej pa bo vse, kar bo ukaz 'grep da *' izpisal na stderr. 3.4 Primer stdout v stderr Tukaj bomo izhodni tok stdout preusmerili v isti opisnik datoteke kot stderr. grep da * 1>&2 Del izpisa, ki bi sicer ¹el na stdout, bo v tem primeru preusmerjen na stderr. 3.5 Primer: stderr v stdout To bo povzroèilo, da bo izhodni tok stderr preusmerjen v isti opisnik datoteke kot stdout. grep * 2>&1 Stderr del izhodnega toka bo tako preusmerjen na standardni izhodni tok - èe boste ta ukaz preko cevovoda povezali s programom less, boste opazili, da bodo vrstice, ki navadno 'izginejo' (ker so izpisane na stderr), tokrat ostale vidne (ker smo jih preusmerili na stdout). 3.6 Primer: stderr in stdout v datoteko Celoten izhodni tok programa bomo preusmerili v datoteko. To vèasih pride prav pri izvajanju opravil v cron-u, ko ¾elite ukaz "uti¹ati". rm -f $(find / -name core) &> /dev/null Ta ukaz (¹e vedno smo pri vnosu v cron) bo izbrisal vse datoteke z imenom 'core', ki se bodo nahajale v kateremkoli imeniku. Naj vas opozorim, da morate biti precej gotovi glede tega, kaj bo ukaz storil, vkolikor boste njegov izhod zavrgli. 4. Cevovodi To poglavje preprosto in praktièno razlo¾i kako uporabljati cevovode in zakaj bi to sploh hoteli. 4.1 Kaj so cevovodi in zakaj bi jih hoteli uporabljati Cevovodi vam omogoèajo (zelo preprosto) povezati izhodni tok enega programa z vhodnim tokom drugega. 4.2 Primer: preprost cevovod s programom sed To je zelo preprost naèin uporabe cevovodov. ls -l | sed -e "s/[aeio]/u/g" V tem primeru se zgodi sledeèe: najprej se izv¹i ukaz 'ls -l', njegov izhodni tok pa je - namesto, da bi se izpisal na terminal - posredovan programu sed, ki nato izpi¹e, kar mu je zaukazano. 4.3 Primer: alternativa ukazu 'ls -l *.txt' To je verjetno bolj neroden naèin izvajanja 'ls -l *.txt', vendar je tu zaradi prikaza delovanja cevovodov in ne zaradi odloèanja o primernosti uporabe ukaza samega. ls -l | grep "\.txt$" Tukaj je izhodni tok ukaza 'ls -l' posredovan programu grep, ki nato izpi¹e vrstice, ki vsebujejo regularni izraz "\.txt$". 5. Spremenljivke Spremenljivke lahko uporabljate prav tako, kot v vseh drugih programskih jezikih. Podatkovnih tipov tukaj ni - spremenljivka lahko vsebuje ¹tevilo, znak ali niz znakov. Spremenljivke vam ni treba deklarirati, ustvari se takoj, ko ji pripi¹ete vrednost. 5.1 Primer: Hello World! z uporabo spremenljivk #!/bin/bash NIZ="Hello World!" echo $NIZ Vrstica 2 ustvari spremenljivko z imenom NIZ in ji priredi niz "Hello World!". VREDNOST spremenljivke nato dobimo tako, da na zaèetek postavimo znak '$'. Èe tega znaka ne boste uporabili, bo izhod programa drugaèen - verjetno ne tak¹en, kot bi si ¾eleli (kar poskusite!). 5.2 Primer: Zelo preprost skript za varnostno kopijo (nekoliko bolj¹i) #!/bin/bash DATOTEKA=/var/moja-varnostna-kopija-$(date +%Y%m%d).tgz tar -cZf $DATOTEKA /home/jaz/ Ta skript prina¹a ¹e eno novost. Za zaèetek morate razumeti ustvarjanje spremenljivke in prirejanje vrednosti v vrstici 2. Gotovo ste opazili izraz '$(date +%Y%m%d)'; èe boste skript tudi pognali, boste ugotovili, da izvr¹i ukaz med oklepaji ter zajame njegov izhod. Ime izhodne datoteke tega skripta bo vsak dan drugaèno, ker smo za ustvarjanje imena uporabili ukaz date s predpisano obliko izhoda (+%Y%m%d). To lahko ¹e nadalje spremenite z drugaènim predpisom oblike. ©e nekaj primerov: echo ls echo $(ls) 5.3 Lokalne spremenljivke Lokalne spremenljivke lahko ustvarimo s kljuèno besedo local. #!/bin/bash HELLO=Hello function hello { local HELLO=World echo $HELLO } echo $HELLO hello echo $HELLO Ta primer nazorno prikazuje uporabo lokalne spremenljivke. 6. Pogojni stavki Pogojni stavki vam omogoèajo odloèitev o izvajanju niza ukazov glede na ovrednotenje doloèenega izraza. 6.1 Teorija Pogojni stavki imajo mnogo oblik. Najbolj osnovna je: if izraz then stavek pri èemer se 'stavek' izvr¹i le, èe je 'izraz' ovrednoten kot resnièen. '2<1' je na primer izraz, ki je ovrednoten kot neresnièen, '2>1' pa kot resnièen. Pogjni stavki imajo tudi drugaène oblike, kot na primer: if izraz then stavek1 else stavek2. 'stavek1' je v tem primeru izvr¹en le, èe je 'izraz' resnièen, sicer pa se izvr¹i 'stavek2' ©e ena oblika pogojnih stavkov: if izraz1 then stavek1 else if izraz2 then stavek2 else stavek3. Tukaj je dodan le del "ELSE IF 'izraz2' THEN 'stavek2'", ki izvr¹i 'stavek2', èe je 'izraz2' ovrednoten kot resnièen. Vse ostalo verjetno razumete (glejte prej¹nje oblike). Nekaj besed o sintaksi: Osnova za konstrukcijo 'if' je v bash tak¹na: if [izraz]; then ukazi, èe je 'izraz' resnièen fi 6.2 Primer: Osnovni pogojni stavek if .. then #!/bin/bash if [ "foo" = "foo" ]; then echo izraz je ovrednoten kot resnièen fi Ukazi, ki se izvr¹ijo, èe je izraz v oglatih oklepajih ovrednoten kot resnièen, so navedeni med 'then' in 'fi' - 'fi' oznaèuje konec pogojenih ukazov. 6.3 Primer: Osnovni pogojni stavek if .. then ... else #!/bin/bash if [ "foo" = "foo" ]; then echo izraz je ovrednoten kot resnièen else echo izraz je ovrednoten kot neresnièen fi 6.4 Primer: pogojni stavki s spremenljivkami #!/bin/bash T1="foo" T2="bar" if [ "$T1" = "$T2" ]; then echo izraz je ovrednoten kot resnièen else echo izraz je ovrednoten kot neresnièen fi 7. Zanke for, while in until To poglavje razlaga zanke for, while in until. Zanka for se nekoliko razlikuje od tak¹ne zanke v drugih programskih jezikih. Omogoèa vam zanko, ki se ponovi za vsako 'besedo' v doloèenem nizu. While ponavlja ukaze, dokler je nadzorni izraz ovrednoten kot resnièen; ustavi se, ko postane izraz neresnièen oziroma ko naleti na ukaz za prekinitev zanke. Zanka until deluje skoraj enako kot while, z razliko, da se ukazi izvajajo, dokler je nadzorni izraz ovrednoten kot neresnièen. 7.1 Primer zanke for #!/bin/bash for i in $( ls ); do echo beseda: $i done V drugi vrstici deklariramo spremenljivko i, kateri bomo pripisali razliène vrednosti iz $( ls ). Tretja vrstica bi bila po potrebi lahko tudi dalj¹a oziroma bi se pred 'done' (4) lahko zvrstilo veè ukazov. 'done' (4) pove, da je ukazov, ki so uporabljali $i konec in da lahko $i pripi¹emo novo vrednost. Ta skript sicer ne poène nièesar koristnega, lahko pa bi mu na primer naroèili, naj izpi¹e le doloèene datoteke (glej prej¹nji primer). 7.2 Zanka for kot v programskem jeziku C Ta zanka je bolj podobna zanki for v C/perl. #!/bin/bash for i in `seq 1 10`; do echo $i done 7.3 Primer zanke while #!/bin/bash STEVEC=0 while [ $STEVEC -lt 10 ]; do echo Stevec kaze $STEVEC let STEVEC=STEVEC+1 done Ta skript 'opona¹a' dobro znano strukturo 'for' (C, Pascal, perl, itd.) 7.4 Primer zanke until #!/bin/bash STEVEC=20 until [ $STEVEC -lt 10 ]; do echo STEVEC $STEVEC let STEVEC-=1 done 8. Funkcije Kot v skoraj vsej programskih jezikih lahko tudi tu zdru¾ite dele programa v funkcije - tako bolj smiselno organizirate program ali pa vadite umetnost rekurzije. Deklaracija funkcije je na moè preprosta: function moja_funkcija { moji_ukazi }. Funkcijo klièete tako, kot bi bila drug program; samo napi¹ete njeno ime. 8.1 Primer funkcij #!/bin/bash function izhod { exit } function hello { echo Hello! } hello izhod echo foo Vrstice 2-4 opisujejo funkcijo 'izhod', vrstice 5-7 pa funkcijo 'hello'. Èe niste popolnoma preprièani, kaj naredi ta skript, kar poskusite! Kot vidite funkcij ni potrebno deklarirati v kakr¹nemkoli posebnem vrstnem redu. Ko boste skript pognali, bo ta najprej klical funkcijo 'hello', nato funkcijo 'izhod'. Vrstice 10 skript ne bo dosegel nikoli. 8.2 Primer funkcije s parametri #!/bin/bash function izhod { exit } function e { echo $1 } e Hello e World izhod echo foo Ta skript je skoraj popolnoma enak prej¹njemu. Glavna razlika je funkcija 'e', ki izpi¹e svoj prvi parameter. Parametri, ki jih podamo funkciji so obravnavani enako kot parametri, podani skriptu. 9. Uporabni¹ki vmesniki 9.1 Uporaba select za ustvarjanje preprostih menijev #!/bin/bash IZBIRE="Pozdrav Izhod" select opt in $IZBIRE; do if [ "$opt" = "Izhod" ]; then echo koncano exit elif [ "$opt" = "Pozdrav" ]; then echo Hello World else clear echo nedovoljena izbira fi done Èe boste pognali ta skript, boste ugotovili, da so to programerjeve sanje za ustvarjanje tekstnih menijev. Konstrukcija je na moè podobna 'for', le da namesto izvr¹itve seznama ukazov povpra¹a uporabnika za vsako 'besedo' v $IZBIRE. 9.2 Uporaba parametrov z ukazne vrstice #!/bin/bash if [ -z "$1" ]; then echo uporaba: $0 imenik exit fi IZVORNA_MAPA=$1 CILJNA_MAPA="/var/varnostne_kopije/" DATOTEKA=home-$(date +%Y%m%d).tgz tar -cZf $CILJNA_MAPA$DATOTEKA $IZVORNA_MAPA Kaj naredi ta skript bi vam moralo biti jasno. Izraz v prvem pogojnem stavku preveri, ali je program dobil parameter ($1). V primeru, da ga ni, se skript konèa z izpisom navodila za uporabo. Preostanek skripta verjetno razumete. 10. Razno 10.1 Branje uporabnikovega vnosa z read Gotovo bodo prilo¾nosti, ko boste ¾eleli, da uporabnik kaj vpi¹e. Tole je eden od mo¾nih naèinov: #!/bin/bash echo Vnesite svoje ime read IME echo "Zdravo, $IME!" Z read lahko dobite tudi veè vrednosti hkrati: #!/bin/bash echo Vnesite svoje ime in priimek read IME PRIIMEK echo "Zdravo, $PRIIMEK $IME!" 10.2 Raèunanje V ukazni vrstici poskusite tole: echo 1 + 1 Èe ste prièakovali, da boste dobili '2', boste nekoliko razoèarani. Kaj storiti, èe ¾elite, da vam BASH pomaga izraèunati nekaj raèunov? Re¹itev je tak¹na: echo $((1+1)) Ta ukaz bo dal bolj 'smiseln' izpis. Isto lahko dose¾ete tudi takole: echo $[1+1] V primeru, da va¹i raèuni vsebujejo ulomke ali te¾jo matematiko, lahko za raèunanje uporabite program bc. Èe na primer v ukazni vrstici po¾enete "echo $[3/4]", boste dobili rezultat 0, ker bash pri izraèunih uporablja le cela ¹tevila. Za pravilen rezultat bo treba pognati "echo 3/4|bc -l", kar bo vrnilo pravilen rezultat - 0,75. 10.3 Iskanje bash Mike (glejte Zahvale) v sporoèilu pi¹e: Primeri vedno uporabljajo #!/bin/bash .. morda bi lahko navedel navodilo kako najti bash, èe ga ni na tem mestu. ©e najbolje je uporabiti 'locate bash', vendar vsi sistemi nimajo programa locate. 'find ./ -name bash' v korenskem imeniku je navadno prav tako uèinkovit. Mesta, ki jih preverite: ls -l /bin/bash ls -l /sbin/bash ls -l /usr/local/bin/bash ls -l /usr/bin/bash ls -l /usr/sbin/bash ls -l /usr/local/sbin/bash (veè mest se trenutno ne morem domisliti... sicer pa sem bash po razliènih sistemih na¹el v enem od navedenih mest. Lahko poskusite tudi 'which bash'. 10.4 Vrnjena vrednost programa Bash shrani vrnjeno vrednost programa v posebno spremenljivko z imenom $?. Sledeèi primer prikazuje kako ugotoviti vrnjeno vrednost programa; predpostavljam, da imenik dada ne obstaja. (Tudi tole je predlagal mike.) #!/bin/bash cd /dada &> /dev/null echo vv: $? cd $(pwd) &> /dev/null echo vv: $? 10.5 Zajemanje izhoda ukaza Ta kratek skript izpi¹e vse tabele iz vseh podatkovnih baz (èe imate seveda name¹èen MySQL). Popraviti morate ukaz mysql, da bo vseboval veljavno uporabni¹ko ime ter geslo. #!/bin/bash DBS=`mysql -uroot -e"show databases"` for b in $DBS ; do mysql -uroot -e"show tables from $b" done 10.6 Veè izvornih datotek Veè izvornih datotek lahko uporabite z ukazom source. __TO-DO__ 11. Tabele 11.1 Primerjalni operatorji za nize (1) niz1 = niz2 (2) niz1 != niz2 (3) niz1 < niz2 (4) niz1 > niz2 (5) -n niz1 (6) -z niz1 (1) niz1 je enak niz2 (2) niz1 ni enak niz2 (3) __TO-DO__ (4) __TO-DO__ (5) niz1 ni prazen (vsebuje enega ali veè znakov) (6) niz1 je prazen 11.2 Primerjave nizov Primerjanje dveh nizov #!/bin/bash NIZ1='niz' NIZ2='Niz' if [ $NIZ1=$NIZ2 ]; then echo "NIZ1('$NIZ1') je enak NIZ2('$NIZ2')" fi if [ $NIZ1=$NIZ1 ]; then echo "NIZ1('$NIZ1') je enak NIZ1('$NIZ1')" fi Andreas Beck je v svojem sporoèilu predlagal uporabo if [ $1 = $2 ]. To ni pretirano dobra ideja, ker boste v primeru, da je $NIZ1 ali $NIZ2 prazen, dobili sporoèilo o napaki. Bolje je uporabiti x$1=x$2 ali "$1"="$2" 11.3 Aritmetièni operatorji + - * / % (ostanek) 11.4 Primerjalni aritmetièni operatorji -lt (<) -gt (>) -le (<=) -ge (>=) -eq (==) -ne (!=) Èe znate programirati v C-ju, preprosto izberite operator, ki ustreza izbranemu operatorju v oklepajih. 11.5 Priroèni ukazi To poglavje je ponovno napisal Kees (glejte Zahvale). Nekateri izmed navedenih ukazov so ¾e sami po sebi skoraj pravi programski jeziki, zato bodo o njih povedane le osnovne stvari. Èe boste ¾eleli bolj poglobljen opis, si lahko ogledate njihove priroènike (man pages). sed (stream editor - urejevalnik toka) Sed je ne-interaktiven urejevalnik. Datoteke ne urejate s premikanjem kurzorja po zaslonu, temveè sed-u podate skript navodil za urejanje ter ime datoteke. Sed bi lahko opisali tudi kot filter. Poglejmo nekaj primerov: $sed 's/za_zamenjavo/zamenjava/g' /tmp/nekaj Sed zamenja niz 'za_zamenjavo' z nizom 'zamenjava', pri èemer bere iz datoteke /tmp/nekaj. Rezultat bo poslan na standardni izhod (navadno konzola), lahko pa seveda na konec ukaza dodate '>zajeto', kar bo preusmerilo izhod v datoteko 'zajeto'. $sed 12, 18d /tmp/nekaj Sed bo izpisal vse vrstice razen 12. in 18. Originalne datoteke ta ukaz ne spremeni. awk (spreminjanje podatkovnih datotek, iskanje ter procesiranje besedila) Obstaja mnogo izvedb programskega jezika AWK (najbolj znana interpreterja sta GNU-jev gawk in 'new awk' mawk). Princip je preprost: AWK i¹èe doloèen vzorec ter izvr¹i niz ukazov, ko ga najde. Ustvaril sem testno datoteko 'nekaj', ki vsebuje naslednje vrstice: "test123 test tteesstt" $awk '/test/ {print}' /tmp/nekaj test123 test Vzorec, ki ga AWK i¹èe je 'test', ukaz, ki ga izvr¹i, ko v datoteki /tmp/nekaj najde vrstico s tem vzorcem, pa 'print'. $awk '/test/ {i=i+1} END {print i}' /tmp/nekaj 3 V primeru, da i¹èete mnogo vzorcev, je pametno zamenjati tekst med narekovaji z '-f datoteka.awk' in napisati vzorce ter ukaze v datoteko 'datoteka.awk'. grep (izpi¹e vrstice, ki vsebujejo iskani vzorec) Ukaz grep smo ¾e nekajkrat sreèali v prej¹njih poglavjih, ko je bilo potrebno izpisati vrstice z iskanim vzorcem. Vendar grep zmore ¹e veè. $grep "i¹èemo tole" /var/log/messages -c 12 Niz "i¹èemo tole" se je v datoteki /var/log/messages pojavil 12-krat. [priznam, ta primer ni popolnoma resnièen - malce sem priredil /var/log/messages :-)] wc (pre¹teje vrstice, besede ter znake) Ta primer ne izpi¹e toèno tistega, kar bi prièakovali. Uporabljena testna datoteka vsebuje naslednje besedilo: "uvod v bash testna datoteka" $wc --words --lines --bytes /tmp/nekaj 1 5 28 /tmp/nekaj Wc se za vrstni red podanih parametrov ne zmeni, temveè izpi¹e statistike vedno enako: <vrstice> <besede> <znaki> <datoteka>. sort (razvrsti vrstice besedila) To pot testna datoteka vsebuje naslednje besedilo: "b c a" $sort /tmp/nekaj Izpis izgleda takole: a b c Ukazi ne bi smeli biti tako enostavni :-) bc (programski jezik za raèunanje) Bc lahko prebere raèune iz datoteke, podane v ukazni vrstici, ali pa preko uporabni¹kega vmesnika. Ta primer prikazuje nekaj ukazov. Navadno bc za¾enem z parametrom -q, ki prepreèi izpis pozdravnega sporoèila. $bc -q 1 == 5 0 0.05 == 0.05 1 5 != 5 0 2 ^ 8 256 sqrt(9) 3 while (i != 9) { i = i + 1; print i } 123456789 quit tput (inicializacija terminala ali poizvedba podatkovne baze terminfo) Manj¹a demonstracija zmo¾nosti programa tput: $tput cup 10 4 Pozivnik se pojavi na (y10,x4) $tput reset Poèisti zaslon, pozivnik pa se pojavi na (y1,x1). (y0,x0) je zgornji levi kot zaslona. $tput cols 80 Izpi¹e ¹tevilo znakov terminala v smeri osi x. Moèno vam priporoèam, da se dobro seznanite z vsaj temi programi. Seveda pa obstaja ¹e mno¾ica drugih majhnih programov, s katerimi v ukazni vrstici lahko izvajate prave èarovnije. [nekaj primerov v tem poglavju je vzetih iz priroènikov in pogosto zastavljanih vpra¹anj] 12. ©e veè skriptov 12.1 Izvajanje ukaza na vseh datotekah v imeniku. 12.2 Primer: Preprost skript za varnostno kopijo (¹e nekoliko bolj¹i) #!/bin/bash IZVORNA_MAPA="/home/" CILJNA_MAPA="/var/varnostne_kopije/" DATOTEKA=home-$(date +%Y%m%d).tgz tar -cZf $CILJNA_MAPA$DATOTEKA $IZVORNA_MAPA 12.3 Preimenovalnik datotek #!/bin/sh # renna: preimenuje veè datotek glede na doloèena pravila # napisal felix hudson Jan - 2000 # najprej preverimo za razliène 'naèine', ki jih program ima. # èe prvi argument ($1) ustreza pogoju, izvedemo doloèen del # programa ter nato konèamo izvajanje skripta # preverimo, ali gre za primer predpone if [ $1 = p ]; then # sedaj se znebimo spremenljivke za naèin ($1) ter predpone ($2) predpona=$2 ; shift ; shift # hiter test, ki preveri, ali so bila podana imena datotek # vkolikor niso bila, je bolje, da ne storimo nièesar, kot # da poskusimo preimenovati datoteke, ki ne obstajajo!! if [$1 = ]; then echo "datoteke niso bile podane" exit 0 fi # ta zanka se ponovi za vsako datoteko, ki je bila podana # skriptu ter preimenuje eno naenkrat for datoteka in $* do mv ${datoteka} $predpona$datoteka done # tukaj konèamo izvajanje exit 0 fi # preverimo, ali gre za preimenovanje konènice # ta del je skoraj enak prej¹njemu, zato nima zaznamkov if [ $1 = k ]; then koncnica=$2 ; shift ; shift if [$1 = ]; then echo "datoteke niso bile podane" exit 0 fi for datoteka in $* do mv ${datoteka} $datoteka$koncnica done exit 0 fi # preverimo, ali gre za zamenjavo vzorca if [ $1 = z ]; then shift # tale del sem vkljuèil zato, da v primeru, ko uporabnik ne # navede parametrov, ne po¹kodujemo datotek if [ $# -lt 3 ] ; then echo "uporaba: renna z [izraz] [zamenjava] datoteke... " exit 0 fi # odstranimo ostale parametre STARO=$1 ; NOVO=$2 ; shift ; shift # ta zanka se ponovi za vsako datoteko, ki je bila podana # skriptu ter jo preimenuje z uporabo programa 'sed', ki v # tekstu iz standardnega vhoda poi¹èe izraz in ga zamenja z # drugim. Tukaj mu na standardni vhod podamo ime datoteke. for datoteka in $* do NOVO_IME=`echo ${datoteka} | sed s/${STARO}/${NOVO}/g` mv ${datoteka} $NOVO_IME done exit 0 fi # èe smo pri¹li do sem, to pomeni, da programu ni bila podan # noben parameter, zato uporabniku povemo, kako se ga uporablja echo "uporaba;" echo " renna p [predpona] datoteke.." echo " renna k [konènica] datoteke.." echo " renna z [izraz] [zamenjava] datoteke.." exit 0 # konèano! 12.4 Preimenovalnik datotek (preprost) #!/bin/bash # preimenuj.sh # enostaven preimenovalnik datotek kriterij=$1 izraz=$2 zamenjava=$3 for i in $( ls *$izraz* ); do datoteka=$i novo_ime=$(echo $i | sed -e "s/$iraz/$zamenjava/") mv $datoteka $novo_ime done 13. Ko gre kaj narobe (razhro¹èevanje) 13.1 Naèini klicanja BASH V prvo vrstico skripta napi¹ite #!/bin/bash -x To bo pri izvajanju izpisalo nekaj koristnih informacij. 14. O tem spisu Sporoèite mi va¹e predloge/popravke oziroma karkoli bi radi videli v tem spisu. Poskusil ga bom posodobiti kakor hitro bo mogoèe. 14.1 (brez) jamèenja Ta spis ne jamèi èesarkoli o èemerkoli. In tako dalje. 14.2 Prevodi Italijanski: William Ghelfi (wizzy at tiscalinet.it) je tukaj Francoski: Laurent Martelli je neznano kje Korejski: Minseok Park http://kldp.org Korejski: Chun Hye Jin unknown ©panski: neznan http://www.insflug.org Domnevam, da obstaja ¹e veè prevodov, vendar o njih nimam informacij. Èe veste za kak¹nega, mi to, prosim, sporoèite. 14.3 Zahvale * Ljudem, ki so ta spis prevedli v druge jezike (prej¹nje poglavje) * Nathanu Hurstu za mnogo popravkov. * Jonu Abbottu za pripombe o aritmetiènih izrazih * Felixu Hudsonu za skript renna * Keesu van den Broeku za mnoge popravke ter ponovno pisanje poglavja o uporabnih ukazih * Mike (pink) je imel nekaj predlogov o iskanju bash in preverjanju datotek * Fieshu za predlog pri poglavju o zankah * Lion je predlagal, da omenim pogosto napako (./hello.sh: Command not found.) * Andreasu Becku za nekaj popravkov in komentarjev. 14.4 Zgodovina Vkljuèeni novi prevodi in nekaj manj¹ih popravkov. Dodal poglavje o uporabnih ukazih, ki ga je ponovno napisal Kess. Upo¹teval ¹e nekaj popravkov in predlogov. Dodani primeri pri primerjavi nizov. v0.8 opustil verzije, domnevam, da je datum dovolj. v0.7 Popravki ter napisanih nekaj starih TO-DO. v0.6 Manj¹i popravki. v0.5 Dodal poglavje o preusmeritvi. v0.4 je izginila s svojega mesta zaradi mojega nekdanjega ¹efa in ta spis je na¹el mesto tam, kjer mora biti: www.linuxdoc.org. prej: ne spominjam se, poleg tega pa nisem uporabljal ne rcs ne cvs :( 14.5 ©e veè virov Uvod v bash (pod BE) http://org.laol.net/lamug/beforever/bashtut.htm Bourne Shell Programming http://207.213.123.70/book/