- A Linux története
- Linux könyvtárszerkezet
- Linux parancssor
- Debian GNU/Linux csomagkezelés
- Linux Shell programozás
Szerző: Sallai András
Copyright © Sallai András, 2011-2020
Licenc: GNU Free Documentation License 1.3
Web: http://szit.hu
- Bevezetés
- Első lépések
- Kivitel
- Formázott kimenet
- Véletlen generálás
- Bevitel
- Változók és az értékadás
- Kifejezés kiértékelése
- Változó deklaráció
- Szelekció
- Szelekció másként
- Iteráció
- Tömbök
- String
- Visszatérési érték
- Karaktersorozat vizsgálatok
- Függvények, eljárás használata
- Változók hatásköre
- Fájl és könyvtár tesztek
- Tesztek a test paranccsal
- Beépített változók
- Fájlok, könyvtárak neveinek kezelése
- Fájlok tartalmának kezelése
- Backup
- Paraméterek használata
- Szignálok elkapása (trap)
- Temp fájlok
- Naplózás
- Függelék
- Példák
- Külső linkek
Bevezetés
A shell programok végrehajtható parancsok gyűjteménye, vagyis egymás után írt parancsok listája egy állományban. Nevezhetjük egyszerűen shell scriptnek is.
A shell scripteknek nem kötelező kiterjesztést megadni. Ha mégis szeretnénk megadni akkor válasszuk az .sh kiterjesztést. A rendszer azonban nem a kiterjesztésből fogja eldönteni, hogy shell script vagy nem az.
Ha egy fájlba parancsokat írunk, azt shell scriptként futtatva a parancsok végrehajtódnak. A unixos rendszerekben a scripteket egy karakterpárral kezdjük:
#!
A rendszer ebből tudja, hogy valamilyen scriptről van szó. Ha egy hexa szerkesztővel nézzük:
hexedit scriptnev
Akkor azt mondhatjuk a következő kódú karakterrel kezdődik:
23 21
A unix alapú rendszerekben a futtatható fájloknak sincs kiterjesztése alapértelmezetten. A Linux például ELF binárisokat futtat. Egy ELF bináris fájl eleje mindig a következő byte sorozattal kezdődik:
7F 45 4C 46
Nézzük meg például az ls parancsunkat (Felhasználóként! Ne rendszergazdaként!).
hexedit /bin/ls
Kilépés Ctrl + C
Ha a hexedit nem lenne telepítve:
apt install hexedit
A scriptek, tehát #! kezdődnek, de honnan tudja a rendszer, hogy milyen scriptről van szó? A #! után adjuk meg az interpreter nevét és elérési útját. Perl script esetén például:
#!/usr/bin/perl
Bash shell script esetén, például:
#!/bin/bash
Python script esetén, például:
#!/usr/bin/python
Első lépések
A script egy futtatható szöveges állomány.
Neked a következőt kell csinálnod.
Létrehozol egy állományt a leírás szerint a /home/felhasználóneved mappába.
cd $HOME
Ezzel a home-ba lépsz. Majd létrehozol egy állományt:touch internet.sh
Ezzel a paranccsal létrehoztál egy üres állományt. Nyisd meg egy szövegszerkesztővel, ha van mcedit akkor azzal pl így:mcedit internet.sh
A fájl fogja tartalmazni azokat a parancsokat amiket le szeretnél futtatni. bash szkript esetén így kell kezdeni az állományt (ez legyen az első sor):#!/bin/bash
Miután beírtad a szükséges parancsokat és elmentetted az állományt, akkor, hogy futtatni tudd ezt a szkriptet futtatási jogot kell neki adni:chmod +x internet.sh
- Szükségünk van egy szövegszerkesztőre, amiben megírjuk a scriptet.
- Futtathatóvá kell tennünk a scriptet.
- Szintaktika:
- chmod jogok script-neve
- Példa:
- chmod +x bar
- chmod 755 bar
- Szintaktika:
- Futtatjuk a scriptet
- Szintaktika:
- bash script-neve
- sh script-neve
- ./script-neve
- Példa:
- $ bash bar
- $ sh bar
- $ ./bar
- Szintaktika:
Megjegyzés
Az utolsó szintaktikában a ./ jelentése: az aktuális könyvtár, de csak ez.
A . (dot) karaktert használhatjuk önmagában is, ez induláskor nem hoz létre egy új shell másolatot.
Szintaktika:
. script-neve
Példa:
$ . foo
Ha egy olyan scriptet indítunk amelyik nem áll le azonnal (például vár adatbevitelre), akkor meggyőződhetünk a fentiekről ha futtatjuk a felhasználó nevén a pstree parancsot. Legyen a példa kedvéért egy joska nevű felhasználó aki a ker.sh nevű scriptet indítja. A scriptet ./ker.sh vagy . ker.sh formában indítja, ekkor lekérdezzük a folyamatfát:
pstree joska
A lehetséges kimenet ./ker.sh esetén:
bash───pstree bash───ker.sh
A lehetséges kimenet . ker.sh esetén:
bash───pstree bash
A különbséget a ps parancs is megmutatja:
ps u
Kapcsolónak csak a „u” kapcsolót kell megadni.
Azt már tudjuk, hogy egy shell sciptet mindig „#!” karakterekkel kezdjük és utána leírjuk az értelmező útvonalát. De hogyan deríthatő ki az értelmező útvonala? Mi most, Bash shell-t szeretnénk használni. A which parancs megmondja, hogy honnan fut egy parancs:
which bash
Megjegyzés
#!/bin/bash # egy soros megjegyzés :' Több soros megjegyzés '
Kivitel
Hozzuk létre első „Helló Világ!” nevű shell scriptünket. készítsünk egy elso.sh nevű fájlt, melynek tartalma a következő: elso.sh
#!/bin/bash echo "Helló Világ!"
Adjunk rá futtatási jogot:
chmod +x elso.sh
Futtassuk:
./elso.sh
Ezek után minden további scriptünket így kell létrehoznunk.
Sorvége:
echo -n "Helló Világ!"
Utóbbi utasítás a -n hatására nem ír a sorvégére sortörést.
Az „Escape” karakterek engedélyezése:
echo -e "Helló Világ!"
A -e kapcsoló engedélyezi az escape karakterek értelmezését a karakterláncokban:
- \a csengő
- \b egy karakter törlése visszafelé
- \c nem ír ki újsor karaktert
- \f lapdobás
- \n új sor
- \r kocsi vissza
- \t vízszintes tabulátor
- \v függőleges tabulátor
- \\ backslash
- \nnn a karakter ASCII kódja nnn (oktálisan)
Az escape karakter a normál karakter egy speciális értelmezése. Az „a” például csengőhang, az „n” sortörés. Azt, hogy speciális escape értelmezés következik egy „\” visszaperjel karakterrel mondjuk meg. A következő parancs például a „Helló” és a „Világ!” szöveget külön sorba írja:
echo -e "Helló\nVilág!"
Formázott kimenet
A printf utasítással a kiírt változókat, értékeket több módon formázhatjuk. Elsőként lássunk egy szimpla változó kiíratást:
printf "%s\n" $HOME
A prrintf segítségével színezhetjük is a kimenetet:
printf "\033[0;32mszínes szöveg\n"
printf "\033[1;33mszínes szöveg\n"
Meg kell jegyezzem, az echo parancs a -e kapcsolóval értelmezi az escape szekvenciákat, és ugyanez a hatás elérhető:
echo -e "\033[1;33mszínes szöveg\n"
Unicode karakter kiíratása is lehetséges a \U escape szekvenciával. Lássuk az „üres” szót:
printf "%b" "Unicode Character (U+7a7a) \U7a7a \n"
A „U” nagy u helyett használhatunk „u” kis u-t is.
Véletlen generálás
Véletlen szám
Az alábbiakban többféle véletlen szám előállítási lehetőséget ismerhetünk meg.
echo $RANDOM
n=$RANDOM echo $n
1 és 3 között egy szám:
echo $(((RANDOM % 3)+1))
De lehet így is:
echo $((1 + RANDOM % 3))
0 és 4 közötti számot véletlenszerűen:
r=$RANDOM R=$((r %= 5)) echo $R
0 és 4 közötti szám:
echo $(( $(od -An -N2 -i /dev/random) % 5))
Véletlenszám az od paranccsal:
od -A n -N 1 -t d < /dev/urandom
A -t d decimális formában kiírásról gondoskodik. A -N 1, egyetlen bájt vételét írja elő.
shuf -i 1-10 -n 1
Ha telepítve van a perl nyelv:
perl -e 'print int rand 10, "\n"; '
Véletlen bemenet
A shuf a bemenetére kapott sorokból véletlenszerűen választ, majd kiírja a kimenetre:
echo -e "1\n2\n3\n4\n5" | shuf -n 1
könyvtár tartalmából véletlenszerűen választás:
ls dir1 | shuf -n 1
Bevitel
Ebben a részben megnézzük, hogyan kérhetünk be a billentyűzetről értékeket.
echo -n "Szó: " read SZOVEG
Egy szöveg bekérése a SZOVEG változóba. A bekérést a read utasítás végzi. Az előtte lévő echo utasítás jelzi a „Szó: ” képernyőre való írásával, hogy egy szó begépelését várjuk. Az echo -n kapcsolója a „Szó: ” szöveg után nem ír sortörést. Így a bekérés rögtön a kettőspont-szóköz után lehetséges.
Bekérés echo nélkül: script.sh
#!/bin/bash read -p "Felhasználónév: " USER echo "A felhasználónév: "$USER
A bekérés szövegét echo nélkül is kitudjuk íratni a read -p kapcsolója segítségével.
Beolvasás tömbbe: script.sh
#!/bin/bash echo -n "Gyümülcsök: " read -a GYUMOLCSOK echo ${GYUMOLCSOK[0]} echo ${GYUMOLCSOK[1]}
A read utasítás a -a kapcsoló hatására indexelt tömbváltozót hoz létre. Lásd „help read”.
A beolvasandó értékeket szóközzel tagolva adjuk meg. Például:
Gyümölcsök: körte alma barack szilva
Jelszó beolvasása: script.sh
#!/bin/bash echo -n "Jelszó: " read -s JELSZO echo echo "A beírt jelszó: " $JELSZO
#!/bin/bash read -p "Jelszó: " -s JELSZO echo echo "A beírt jelszó: " $JELSZO
Alapértelmezett szöveg megadása: script.sh
#!/bin/bash read -e -i "joska" -p "Felhasználónév: " USER echo "A beírt felhasználónév: "$USER
A „-e” kapcsoló is szükséges.
Változók és az értékadás
A változók kis és nagybetű érzékenyek. A SZAM és a szam változó két különböző változó. Az átláthatóság érdekében a változóneveket nagybetűvel szokás írni.
SZAM=3 SZOVEG="alma" echo $SZAM echo $SZOVEG
Az értékadó operátor előtt és után nem hagyhatunk whitespace karaktert, mert akkor a SZAM vagy SZOVEG változót egy parancsnak venné.
Kifejezés kiértékelése
expr 1 + 3
Az 1+3 összegét, azaz 4-et ad vissza script.sh
#!/bin/bash A=3 B=7 expr $A + $B
#!/bin/bash A=3 B=7 C=`expr $A + $B` echo $C
#!/bin/bash A=3 B=7 C=`expr $A "*" $B` echo $C
#!/bin/bash A=3 B=7 C=`expr \( $A "*" $B \) / 2 ` echo $C
#!/bin/bash A=3 B=7 C=`echo \( $A "*" $B \) / 2 | bc` echo $C
Gyökvonás: script.sh
#!/bin/bash echo sqrt\(9\) | bc
Hatványozás: script.sh
#!/bin/bash echo 2 ^ 8 | bc
Dupla zárójel
A következő program a szam változó értéket 1-gyel növeli: szamol.sh
#!/bin/bash szam=3 szam=$((szam+1)) echo $szam
Variációkat láthatunk a növelésre:
szam=$((szam+1)) ((szam=szam+1)) ((szam+=1)) ((szam++))
A let kulcsszó használata
#!/bin/bash szam=3 let "szam=szam+1" echo $szam
Variációk a let kulcsszó használatára:
let "szam=szam+1" let "szam+=1" let "szam++" let szam++
A bc
#!/bin/bash declare -i szam=4 bc <<< "$szam+2"
#!/bin/bash declare -i szam=4 echo "$szam+2" | bc
Változó deklaráció
#!/bin/bash declare -i szam szam=4 szam=szam+1 szam+=1 echo $szam
#!/bin/bash declare -i szam=4 szam=szam+1 szam+=1 echo $szam
Szelekció
if
#!/bin/bash SZAM=2 if [ $SZAM -eq 2 ] then echo "Egyenlo" else echo "Negy egyenlo" fi
Az -eq egyenlőséget vizsgál. Használható még a „=” vagy a „==” karakterek is, viszont ezen operátorok előtt és után kötelező egy vagy több whitespace karakter.
#!/bin/bash SZAM=2 if [ $SZAM -ne 2 ] then echo "Nem egyenlő kettővel" else echo "Egyenlő kettővel" fi
A -ne azt jelenti nem egyenlő. Használható helyette a != alak is.
#!/bin/bash SZAM=2 if [ $SZAM -gt 2 ] then echo "Nagyobb" else echo "Kisebb vagy egyenlő mint kettő" fi
#!/bin/bash SZAM=2 if [ $SZAM -lt 2 ] then echo "Kisebb mint kettő" else echo "Nagyobb vagy egyenlő mint kettő" fi
#!/bin/bash SZAM=2 if [ $SZAM -le 2 ] then echo "Kisebb vagy egyenlő mint kettő" else echo "Nagyobb mint kettő" fi
#!/bin/bash SZAM=2 if [ $SZAM -ge 2 ] then echo "Nagyobb vagy egyenlő" else echo "Kisebb" fi
And operátor
Egyszerre nem csak egy, hanem több feltételt is meg szeretnénk vizsgálni.
if [[ $num -eq 3 && "$str" == foo ]] then # Utasítások fi
elif
#!/bin/bash read -p "Gyümölcs: " fruit if [ "$fruit" = "alma" ]; then echo "Ez alma" elif [ "$fruit" = "körte" ]; then echo "Ez körte" else echo "Nem alma és nem körte" fi
select
#!/bin/bash select i in "egy" "kettő" "három" do echo Ezt választottad: echo $i done
Kiírja az „egy”, „kettő”, „három” szavakat sorszámokkal bevezetve. Valójában egy ciklus is elindul. Mindig várja, hogy válasszunk egyet. A ciklus a Ctrl + C billentyűkombinációval is.
A ciklus persze megszakítható a break utasítással a cikluson belülről is. valaszt.sh
#!/bin/bash select i in "egy" "kettő" "három" "kilépés" do echo Ezt választottad: echo $i if [[ "$i" = "kilépés" ]] ; then break fi done
És, vagy logikai operátorok
Vagy: script.sh
#!/bin/bash A=0 B=1 if [[ $A -eq 1 || $B -eq 1 ]] then echo "Ok" else echo "Nem ok" fi
És: script.sh
#!/bin/bash A=0 B=1 if [[ $A -eq 1 && $B -eq 1 ]] then echo "Ok" else echo "Nem ok" fi
Kevert: script.sh
#!/bin/bash A=1 B=0 C=1 if [[ ($A -eq 1 || $B -eq 1) && $C -eq 1 ]] then echo "Ok" else echo "Nem ok" fi
Szelekció másként
Szimpla szelekció
#!/bin/bash A=1 [ $A -eq 1 ] && echo "Ok" || echo "Nem ok"
Vagy logikai operátor
#!/bin/bash A=1 B=1 [ $A -eq 1 ] && [ $B -eq 1 ] && echo "Ok" || echo "Nem ok"
És logikai operátor
#!/bin/bash A=1 B=1 [ $A -eq 1 ] && [ $B -eq 1 ] && echo "Ok" || echo "Nem ok"
Vegyes logikai operátorok
#!/bin/bash A=1 B=1 C=0 ([ $A -eq 1 ] || [ $B -eq 1 ]) && [ $C -eq 1 ] && echo "Ok" || echo "Nem ok"
Több ágú elágazás
echo "[O]lvas" echo "[H]ozzáfűz" echo "[S]zerkeszt" read menupont case "$menupont" in "O" | "o" ) echo "Olvasási műveletek" ;; "H" | "h" ) echo "Hozzáfűzési műveletek" ;; "S" | "s" ) echo "Szerkesztési műveletek" ;; esac
Iteráció
for
Számok 1-től – 10-ig, variációk:
for i in `seq 1 10` do echo $i done
for i in `seq 1 10`; do echo $i ; done
for i in 1 2 3 4 5 6 7 8 9 10 do echo $i done
Egy könyvtár tartalmát végig vesszük:
for i in `ls /etc` do echo $i done
A példában listázzuk az /etc könyvtár tartalmát.
Zip fájlok feldolgozása:
#!/bin/bash for file in * do if [[ "$file" = *.zip* ]] then echo "$file" fi done
#!/bin/bash for (( n=0; n<10; n++ )) do echo "Helló" done
#!/bin/bash for (( n=0; n<10; n++ )) do echo $n done
while
Amíg típusú ciklus (while)
#!/bin/bash SZAMLALO=1 while [ $SZAMLALO -lt 11 ] do echo $SZAMLALO let SZAMLALO=SZAMLALO+1 done
Számok bekérése nulla végjelig:
#!/bin/bash SZAM=1 while [ $SZAM -ne 0 ] do echo -n "Szám: " read SZAM done
Számok bekérése nulla végjelig, közben összegzés.
#!/bin/bash SZAM=1 SZUM=0 while [ $SZAM -ne 0 ] do echo -n "Szám: " read SZAM let SZUM=$SZUM+$SZAM done echo "Összeg: " $SZUM
A let nélkül sztringkét adja össze.
Végtelen ciklus létrehozása:
while true do #amit csinálunk a végtelen ciklusban done
Másik módszer a végtelen ciklusra:
while : do #amit csinálunk a végtelen ciklusban done
while : do echo -n "Számot: " read SZAM if [ $SZAM -lt 1 ] then exit 0 fi done
Fájl olvasása
#!/bin/bash while read sor do echo $sor done < gy.txt
#!/bin/bash cat gy.txt | while read sor do echo $sor done
Könyvtár tartalmának olvasása
A .txt kiterjesztésű fájlok olvasása: script.sh
#!/bin/bash DIR=konyvtar/alkonyvtar cd $DIR find $DIR -name '*.txt' | while read sor do echo $sor done
until
#!/bin/bash SZAMLALO=1 until [ $SZAMLALO -gt 10 ] do echo $SZAMLALO let SZAMLALO=SZAMLALO+1 done
Tömbök
tomb=( "egy" "kettő" "három")
Hivatkozás egy tömbelemre:
echo ${tomb[1]}
Ez a második elemet adja vissza, vagyis az indexelés 0-val kezdődik.
A tömb elemei így is felvehetők:
tomb[0]=egy tomb[1]=kettő tomb[2]=három echo ${tomb[1]}
A tömb tulajdonságai
#!/bin/bash ${tomb[*]} # a tömb összes eleme ${!tomb[*]} # a tömb összes indexe ${#tomb[*]} # a tömb elemeinek száma ${#tomb[0]} # a 0-dik elem hossza
A tömb bejárása
#!/bin/bash etelek=( "Halsaláta" "Zöldségkör" "Húsleves" "Narancs-joghurt" ) count=${#etelek[@]} for item in ${ketogenEtelek[*]} do echo $item done
A tömb bejárása a for in szerkezettel, csak akkor működik, ha nincs szóköz a tömb elemeiben. Ha a tömb elemei szóközöket is tartalmaznak, akkor a következő ciklus alkalmas bejárásra:
#!/bin/bash etelek=( "Halsaláta (uborka, tonhal, tejföl)" "Zöldségkör (tejföl, túró, zöldségek)" "Húsleves" "Narancs joghurt" ) count=${#etelek[@]} for (( i=0; i<${count}; i++)) do echo ${ketogenEtelek[$i]} done
#!/bin/bash tomb=( "alma" "körte" "barack" "szilva" ) for i in "${tomb[@]}" do echo $i done
String
Hossz
SZOVEG="Nagy János" meret=${#SZOVEG} echo $meret
SZOVEG="abc123" HOSSZ=$(printf "%s" "$SZOVEG" | wc -c)
echo ${#SZOVEG} echo -n $SZOVEG | wc -m echo -n $SZOVEG | wc -c printf $SZOVEG | wc -m expr length $SZOVEG expr $SZOVEG : '.*'
Kisbetű, nagybetű
STR="Alma" echo $STR # alma echo ${STR,,} # alma echo ${STR^^} # ALMA
A fenti megoldás, csak a 4.x Bash verziótól működik.
Használhatjuk a tr parancsot, ami viszont nem viszi a magyar ékezetes karaktereket.
STR="Alma" echo "$STR" | tr '[:upper:]' '[:lower:]'
Megoldás lehet még az awk használata:
echo "ÁRVÍZTŰRŐ" | awk '{print tolower($0)}'
echo "Árvíztűrő" | awk '{print toupper($0)}'
A Bash megoldás esetén használhatunk egyetlen ^ vagy , karaktert. Ekkor csak az első karakterre vonatkozik a beállítás.
STR=árvíztűrő; echo ${STR^} Árvíztűrő
Milyen betűk legyenek nagybetűk:
STR=árvíztűrő; echo ${STR^^[v,z]} árVíZtűrő
Ékezetlenítés
Repülő ékezetek, normál ékezet helyett:
echo árvíztűrő | iconv -f UTF-8 -t ASCII//TRANSLIT
# apt install unaccent
$ echo árvíztűrő | unaccent utf-8 arvizturo
$ echo árvíztűrő | sed 'y/áíéóöőúüű/aieooouuu/'
Tartalmaz-e?
#!/bin/bash if [[ $a == *"é"* ]] then echo "Van benne é betű" else echo "Nincs benne é betű" fi
String bejárása karakterenként
#!/bin/bash a=béla for (( i=0; i<${#a}; i++ )) do echo "${a:$i:1}" done
Regex
Az [a-z] mint megfelel az angol ábécé betűinek plusz áíóöúü betűknek, de nem felel meg a ő és ű betűknek.
#!/bin/bash a=belí if [[ $a =~ ^[a-z]+$ ]] then echo "Megfelel" else echo "Nem felel meg" fi
String darabolása
#!/bin/bash str="alma:körte:barack:szilva" IFS=':' read -ra tomb <<< "$str" echo ${tomb[0]}
Heredoc szintaxis
#!/bin/bash date=$(date "+%Y-%m-%d") cat << EOT ========== $date Óra: Téma: Hiányzók: 1 óra: 2 óra: 3 óra: Dolgozat: Hetes: EOT
Üres sorok törlése
cat fajl.txt | sed '/^$/d'
Adott karakterek törlése
A következő karakterek törlése:
. ? – , |
cat fajl.txt | sed '/[\.?-\,]//g'
Visszatérési érték
Vizsgáljunk meg egy program végrehajtásának sikerességét. A példában az smbmount parancsot vizsgáljuk a végrehajtás sikerességéről.
#!/bin/bash smbmount //server/megosztasnev -o username=joe,password=titok,uid=joe,gid=csoport if [ $? == 0 ] then echo echo "A végrehajtás sikeres" echo else echo echo "Hiba a végrehajtás során" echo fi
Karaktersorozat vizsgálatok
Operátorok:
= | egyenlő |
!= | nem egyenlő |
< | rövidebb |
> | hosszabb |
-z $NEV | a NEV üres |
#!/bin/bash ELSO="Kati" MASODIK="Kati" if [ $ELSO = $MASODIK ] then echo Egyezik else echo Nem egyezik fi
Üres vagy nem üres a string:
#!/bin/bash ELSO="" if [ -z $ELSO ] then echo Üres else echo Nem üres fi
Az ASCII táblában előrébb vagy hátrább van-e:
#!/bin/bash ELSO="szilva" MASODIK="zalma" if [ $ELSO \> $MASODIK ] then echo "Hátrébb van" else echo "Előrébb van" fi
vagy így:
#!/bin/bash ELSO="szilva" MASODIK="zalma" if [[ $ELSO > $MASODIK ]] then echo "Hátrébb van" else echo "Előrébb van" fi
#!/bin/bash ELSO="s*" # minta egyezés if [[ $ELSO == s* ]] then echo "s-el kezdődik" else echo "Nem s-el kezdődik" fi
#!/bin/bash ELSO="s*" # literális egyezés if [[ $ELSO == "s*" ]] then echo "s* van benne" else echo "Nem s* van benne" fi
#!/bin/bash ELSO="s*" # literális egyezés if [ "$ELSO" == "s*" ] then echo "s* van benne" else echo "Nem s* van benne" fi
Függvények, eljárás használata
Függvény: minta.sh
function kiir() { echo "Helló Világ" } kiir
Függvény paraméterrel: minta.sh
function kiir() { echo $1 } kiir "Ezt írd ki"
Bemenő paraméter és visszatérési érték: fg.sh
#! /bin/bash function dupla() { local res=$(echo "$1 * 2" | bc) echo "$res" } result=$(dupla 3) echo $result
Ez a megoldás is működik, de az előbbi korrektebb: vissza.sh
#! /bin/bash function dupla() { res=$(echo "$1 * 2" | bc) } dupla 3 echo $res
Példa:
#!/bin/bash # Rekurzívan az alkönyvtárakban is átnevez minden fájlt kisbetűsre # Jelenleg csak fájlokra működik, könyvtárakra nem. # Latin2-es környezetben működik (1 karakter == 1 byte), UTF-8-ban nem. # UTF-8-as környezetben a tr helyett a sed parancsot használjuk! function files() { for i in * ; do if [ -f "$i" ]; then j=`echo "$i" | tr '[:upper:]' '[:lower:]'` if [ "$i" != "$j" ]; then mv -i "$i" "$j" fi fi done } function dirs() { for i in *; do if [ -d "$i" ]; then cd "$i" dirs files cd .. fi done } dirs files
Változók hatásköre
A következő script szemlélteti a változók hatáskörét. A local kulcsóval létrehozott függvényen belüli változó nem látszik csak a függvényben. Az $ERO nevű változó viszont globális, mindenhol látszik.
#!/bin/bash ERO="85" function csokkent { local MERTEK=5 echo "Erő csökkentése..." ERO=`expr $ERO - $MERTEK` } echo "Erő: $ERO" csokkent echo "Erő csökkentés után: $ERO" echo "Csökkentés mértéke: $MERTEK"
Külső változó felhasználása:
#!/bin/bash szam=45 function csinal() { szam=100 echo "Működik" } csinal echo "$e"
Fájl és könyvtár tesztek
Használható kapcsolók listája
- -b filename A fájl speciális blokk?
- -c filename A fájl speciális karakterfájl?
- -d directoryname A könyvtár létezik?
- -e filename A fájl létezik?
- -f filename A fájl általános fájl, nem egy könyvtár?
- -G filename Ha a fájl létezik, érvényes tulajdonos érvényes csoportazonosító?
- -g filename true ha fájl létezik és van set-group-id
- -k filename Sticky bit
- -L filename Szimbolikus link
- -O filename True ha fájl létezik és az felhasználó érvényes azonosító.
- -r filename Ellenőrzés, ha a fájl olvasható.
- -S filename Ellenőrzés, ha a fájl socket
- -s filename Ellenőrzés, ha a fájl nem nonzero méretű
- -u filename Ellenőrzés, ha set-ser-id bit be van állítva
- -w filename A fájl írhatóságának ellenőrzés
- -x filename A fájl futtathatóságának olvasása
A fájl létezésének ellenőrzése
#!/bin/bash file="adat.txt" if [ -e $file ]; then echo "A fájl létezik" else echo "A fájl nem létezik" fi
Első paraméter létezésének vizsgálata
#!/bin/bash if [ -z "$1" ]; then echo usage: $0 directory exit fi
Könyvtár vizsgálat
Példa a könyvtárvizsgálatra:
if [ -d "$DIRECTORY" ]; then # Mit tegyünk, ha a $DIRECTORY könyvtár létezik fi
A könyvtár neve (esetleg útvonala) a $DIRECTORY változóban találjuk.
Ha a könyvtár nem létezik:
if [ ! -d "$DIRECTORY" ]; then # Mit tegyünk, ha a $DIRECTORY nem létezik fi
Parancs kimenete
[ -z "`ls`" ] && echo "Nincs fájl"
A [ -z az ls által visszaadott sztring hosszát vizsgálja, hogy az 0 értékű-e.
[ -n "`ls`" ] && echo "Van valamilyen fájl"
A [ -n az ls által visszaadott sztring hosszát vizsgálja, hogy az nagyobb-e mint 0.
Tesztek a test paranccsal
Az if utasítást után a test parancs is használható feltételek meghatározására. A következőkben erre látunk példát.
test <KIFEJEZÉS>
[ <KIFEJEZÉS> ]
A két utasítás visszatérhet 0-val (TRUE) vagy 1 (FALSE) értékekkel.
#!/bin/bash if test -e /etc/group then echo "A csoportfájl létezik..." >&2 else echo "Valami nem kerek!" >&2 exit 1 fi
A test utasítás után a kifejezés egy -e kapcsolóval kezdődik. Azt mondja egy fájl létezését akarjuk tesztelni. Ez után következik, hogy melyik fájlt szeretnénk tesztelni.
A fenti utasításnak teljesen megfelel a „[” karakter. Ha megnézzük az /usr/bin könyvtárat, akkor találni fogunk ott egy ilyen futtatható programot.
#!/bin/bash if [ -e /etc/group ] then echo "A csoportfájl létezik..." >&2 else echo "Valami nem kerek!" >&2 exit 1 fi
Beépített változók
$0 | A script neve |
$1 | paramét1 |
$2 | paramét2 |
$3 | paramét3 |
$4 | paramét4 |
$5 | paramét5 |
$6 | paramét6 |
$7 | paramét7 |
$8 | paramét8 |
$9 | paramét9 |
$# | argumentumok száma |
$@ | az összes argumentum |
$? | az utolsó folyamat kilépési kódja |
$LINENO | a script aktuális sora |
$HOSTNAME | hol fut a script |
$USER | a scriptet futtató felhasználó |
$SECONDS | a futtatás kezdete óta eltelt idő |
$RANDOM | minden hivatkozáskor más véletlen számot ad |
Fájlok, könyvtárak neveinek kezelése
A következő példákban egy könyvtárban található fájlok vagy alkönyvtárak tartalma helyett, azok nevein hajtunk végre valamit. Jelenleg csak kiíratjuk a nevüket. olvas.sh
#!/bin/bash FAJLOK='*.txt' ls $FAJLOK | while read next_file do echo $next_file done
#!/bin/bash DIR=/home/utvonal cd $DIR for FILE in * do echo Könyvtárnevek: $FILE done
#!/bin/bash DIR=/home/utvonal cd $DIR find $DIR -name '*.txt' | while read filename do echo $filename done
Fájlok tartalmának kezelése
A következő példa bemutatja hogyan tudjuk olvasni egy fájl tartalmát.
while read sor do echo $sor done < gy.txt
Ebben a példában is egy fájl tartalmát olvassuk, kicsit másként.
cat gy.txt | while read sor do echo $sor done
Külső linkek
- http://tldp.org/LDP/Bash-Beginners-Guide/html/ 2018)
- http://tldp.org/LDP/abs/html/ (Advanced Bash-Scripting Guide; 2018)
- http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html (2018)
- http://www.freeos.com/guides/lsst/ch02sec01.html (2018)
- http://www.freeos.com/guides/lsst/ (2018)
- http://user.it.uu.se/~matkin/documents/shell/#simple_commands (2018)
- http://www.arachnoid.com/linux/shell_programming.html (2018)
- http://www.inf.u-szeged.hu/~kato/teaching/unix/unix3.html (2018)
- http://www.arcania.hu/Informatika/linux/commands.html (2018)
- http://www.linuxconfig.org/Bash_scripting_Tutorial (2018)
- http://mywiki.wooledge.org/BashPitfalls (2018)
- http://wiki.koczka.hu/index.php/Kezd%C5%91lap (Operációs rendszerek; 2018)
- http://wiki.bash-hackers.org (2018)
- http://wiki.bash-hackers.org/commands/classictest (2018)
- http://www.comptechdoc.org/os/linux/programming/script/linux_pgscriptintro.html (2018)
- http://www.linuxjournal.com/content/bash-arrays (2018)
- http://www.linuxjournal.com/article/2807 (dialog parancs; 2018)
- http://www.faqs.org/docs/Linux-HOWTO/Bash-Prog-Intro-HOWTO.html (2018)
- http://hup.hu/node/111049 (Hasznos fórum téma; 2018)
- http://www.shelldorado.com/scripts/categories.html (2018)
- http://www.linuxquestions.org/ (2018)
- https://ryanstutorials.net/bash-scripting-tutorial/bash-variables.php (Változók; 2018)
- https://www.linuxjournal.com/content/return-values-bash-functions (2020)
- https://linuxhint.com/return-string-bash-functions/ (2020)
- https://github.com/ruanyf/simple-bash-scripts (2020)