Index 🏠 || 🔝 Nahoru


Publikováno:

Aktualizováno

Série »Linux shell«

Kategorie:

PSKáčko

Tagy:

Unixový shell se dá použít nejen pro interaktivní práci, ale i jako programovací jazyk. Jednotlivé příkazy můžeme zapsat do souboru a tento soubor nechat interpretovat příkazovým interpretem. Tento soubor je potom označován jako skript nebo shellový skript.

Hlavička

Aby bylo možné skript jednoduše spouštět je nutné opatřit ho hlavičkou: První řádek začíná dvojicí znaků #! a pokračuje cestou k příkazovému interpretu:

1
#!/bin/bash

Tento mechanizmus je zcela obecný a uplatní se stejně i pro skripty v jiný jazycích. Například pro programovací jazyk Python by hlavička mohla vypadat takto:

1
#!/usr/bin/python

Aby se skript choval jako každý jiný program je jeho správná hlavička podmínkou nutnou nikoli postačující. Skript musí být spustitelný (chmod a+x ~/bin/mujSkript.sh) a musí být umístěn tak, aby ho příkazový interpret našel. Pokud je vše toto splněno může ho uživatel spouštět, jako by to byla běžná součást sytému.

1
$ mujSkript.sh

Příkaz . (tečka)

Ano . je opravdu příkaz. Výše popsaný způsob spouštění má za následek, že námi vytvořený skript je spuštěn v podřízeném shell-u. To mimo jiné znamená, že změny provedené v proměnných prostředí nebudou po dokončení skriptu viditelné. Použijeme-li příkaz:

1
$ . soubor

…bude shell postupně číst soubor a jednotlivé příkazy vykonávat v aktuálním shellu. Výsledek bude stejný jako kdyby uživatel zadával příkazy rovnou v interaktivním prostředí.

Poznámky

Poznámky se zapisují za znak #. Vše od znaku # do konce řádku je interpretem ignorováno.

Přebírání parametrů (argumentů)

Skriptům lze stejně jako programům předávat parametry. Ty jsou uvnitř skriptu dostupné po mocí speciálních proměnných.

Proměnná Význam
$0 jméno skriptu
$1 první parametr
$2 druhý parametr
$n n-tý parametr, n nabývá hodnoty 1 až 9
${n} libovolný n-tý parametr
$# číslo posledního parametru
$* seznam všech parametrů — stejné jako "$1 $2 $3 ..."
$@ seznam všech parametrů — stejné jako "$1" "$2" "$3" ...

Příkaz shift N vymaže prvních N parametrů a posune význam proměnných $n a ${n}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash
# Soubor:    mujSkript.sh
#  Popis:    Ukázka předávání parametrů
############################################################

echo Jmenuji se: $0
echo Parametry: $@
echo první: $1
echo třetí: ${3}

shift 3
echo ">>> první 3 parametry byli vymazány"
echo Parametry: $@
1
2
3
4
5
6
7
$ ./mujSkript.sh toto je ukazka predavani parametru
Jmenu ji se: ./mujSkript.sh
Parametry: toto je ukazka predavani parametru
první: toto
třetí: ukazka
>>> první 3 parametry byli vymazány
Parametry: predavani parametru

Jak bylo uvedeno každý program, který ukončí svou činnost korektně vrací jako svou návratovou hodnotu 0. Pokud se v průběhu programu objeví chyba, dává o tom program vědět svou nenulovou návratovou hodnotou.

Okamžité ukončení skriptu s konkrétní návratovou hodnotou vyvolá příkaz exit N.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash
# Soubor:    navrat.sh
#  Popis:    Ukázka návratové hodnoty
############################################################

if [ $1 ] && [ $1 = 'ano' ]; then
    echo OK
    exit 0
else
    echo napiš ano
    exit 1
fi
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$./navrat
napiš ano
$ echo $?
1

$./navrat NEE
napiš ano
$ echo $?
1

$./navrat ano
OK
$ echo $?
0

Funkce

Shell umožňuje vytvářet funkce. Funkce se chová stejně jako samostatný skript, včetně předávání parametrů a návratové hodnoty.

Ukončení funkce s konkrétní návratové hodnotou je zajištěna příkazem return N.

Sada proměnných pro předávání parametrů funguje stejně jako u skriptu.

Syntaxe funkce v shellu:

1
2
3
4
5
název() {
    příkaz
    příkaz
    ....
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash
# Soubor:    scitani.sh
#  Popis:    Ukázka funkce
############################################################


plus() {
    echo ${1}+${2}=$[ $1 + $2 ]
}

plus $1 $2
plus $3 $4
plus $5 $6
1
2
3
4
$ ./scitani.sh 1 2 3 4 5 6
1+2=3
3+4=7
5+6=11

Podmínky cykly

Užití podmínek a cyklů není vázáno jen na skripty. Stejně tak je možné je použít v interaktivní práci.

V následujících ukázkách jsem zvolil způsob zápisu, který mi připadá přehledný, ale platí, že středník ; může být zaměněn za konec řádku a naopak.

if — podmíněné vykonání

Syntaxe obecně vypadá takto:

1
2
3
4
if VYRAZ; then
    PRIKAZ
    ....
fi
1
2
3
4
5
6
7
if VYRAZ; then
    PRIKAZ
    ....
else
    PRIKAZ
    ....
fi
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
if VYRAZ; then
    PRIKAZ
    ....
elif VYRAZ; then
    PRIKAZ
    ....
elif VYRAZ; then
    PRIKAZ
    ....
...
else
    PRIKAZ
    ....
fi

VYRAZ:

  • VYRAZ je příkaz nebo posloupnost příkazů oddělených pomocí metaznaku || (logický součet — nebo) nebo metaznaku && (logický součin — and).
  • O pravdivosti nebo nepravdivosti výrazu rozhoduje jeho návratová hodnota.
  • VYRAZ je možné negovat pomocí znaku ! na jeho začátku.

Jako VYRAZ se velice často používá program test respektive jeho synonymum [. Podmínka potom vypadá jako by byla zapsána do hranatých závorek, ale ve skutečnost je volán program test.

Program test:

  1. porovnává řetězce
  2. porovnává celá čísla
  3. testuje typy souborů a jejich stáří

Více se dočtete v manuálové stránce programu test.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/bash
# Soubor:    if.sh
#  Popis:    Ukázka podmínky
############################################################

if [ -z $1 ]; then
    echo program nemá žádné parametry
else
    echo program  $# parametrů
fi

case — shoda se vzorem

Vícenásobné větvení pomocí vzorů ukážeme na příkladu:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash
# Soubor:    case.sh
#  Popis:    Ukázka CASE
############################################################

case $1 in
    ahoj|nazdar|cau) echo pozdrav;;
    [tT]*) echo slovo zacina na T;;
    *e*) echo slovo obsahuje e;;
    *) echo cokoliv jiného;;
esac
  • Větev ukončují dva středníky.
  • Znak | slouží jako oddělovač vzorů ve významu nebo.
  • Pro vzory platí stejná pravidla jako pro expanzi jmen souborů.

for — pro každou položku seznamu

Syntaxe cyklu for vypadá takto:

1
2
3
4
5
for PROMENNA in SEZNAM; do
    PRIKAZ
    PRIKAZ
    .....
done

Nejprve se expanduje SEZNAM. PROMENNA nabývá při každé iteraci postupně jedné z hodnot SEZNAMu.

1
2
3
for cislo in 1 2 3 4; do
    echo cislo je $cislo
done

Jako seznam může ale být uvedeno neúplné jméno souboru

1
2
3
4
for soubor in *; do
    echo menim casove razitko: $soubor
    touch $soubor
done

… nebo program, který seznam vrátí.

1
2
3
for cislo in $(seq 5 10); do
    echo cislo je $cislo
done

while, until — opakování na základě podmínky

Syntaxe cyklu while a until vypadá naprosto stejně. Jediný rozdíl je v podmínce. Iterace cyklu while se vykoná pokud podmínka platí. Iterace cyklu until se vykoná pokud podmínka neplatí.

K okamžitému ukončení těla cyklu slouží příkaz break k přeskočení zbytku těla cyklu příkaz continue.

1
2
3
4
5
while VYRAZ; do
    PRIKAZ
    PRIKAZ
    ....
done

VYRAZ má stejný význam jako u podmínky if.

1
2
3
4
while ping -c 3 172.16.6.53 &>/dev/null; do
    echo PC je zapnute.
done
echo K PC se není možné připojit.

Standardní vstup s těla skriptu

Častokrát požadujeme, aby program spuštěný z těla skriptu byl “nakrmen” vstupními daty. Pro přesměrování standardního vstupu ze souboru sice slouží metaznak < ale vytváření samostatného souboru pro vstupní data není vždy efektivní. Proto použijeme metaznak <<.

1
2
3
4
5
6
prikaz <<OMEZOVAC
DATA
DATA
DATA
....
OMEZOVAC
  • OMEZOVAC je libovolná posloupnost znaků.
  • Ukončovací OMEZOVAC musí být uveden nasamostatném řádku.
  • Ve vstupních datech je možné zapsat i proměnné.
  • pokud je “OMEZOVAC” v uvozovkách dereference proměnných se neprovádí.
1
2
3
4
cat <<EOF | wc -w
u textu, tery jsem sem napsal se provede
pocitani slov. Pocet slov je:
EOF

Související posty