Vytváření skriptů, proměnné prostředí

Příkaz alias

Příkaz alias vytváří zástupné názvy (aliasy) příkazů. Příkazy se uvádějí za rovnítko do uvozovek se všemi parametry (bez mezer kolem rovnítka!). Další parametry příkazy přejímají z příkazové řádky, jako by šlo o volání skutečného příkazu z aliasu.

Alias lze odstranit příkazem unalias.

SYNOPSIS

alias='program s argumenty'

EXAMPLES

alias ls='/usr/bin/ls --color=auto'
ls spustí /usr/bin/ls --color=auto. V aliasu musí být absolutní cesta, jinak by se volal rekurzivně alias do nekonečna.

Spuštění příkazů uložených v souboru (skriptu)

Pokud často spouštítě nějakou sekvenci příkazů, můžete jí napsat do souboru (obvykle s příponou sh) a pak příkazy spouštět.

  1. příkazem bash (nebo sh), což je v podstatě nové spuštění interpretu.
    (Takto ovsem nelze procedure predavat pozicni parametry z prikazove radky)
    $ sh < program

    V takto spustenem skriptue se mohou vyuzivat argumenty z prikazove radky, program nemusi mit nastaveno pravo pro spusteni - x.

    $ sh program
  2. Pokud je skript odladen a ma se pouzivat, je mozne nastvit skriptu pristupova prava na spustseni a potom jej spoustet pouze jeho jmenem. Takto spustenemu skriptu lze predavat argumenty z prikazove radky.

     $ ls -l program
     -rw-r--r-- 1 krtek hromada 485 Nov 12 11:25 program
     $ chmod u+x program
     $ ls -l program
     -rwxr--r-- 1 krtek hromada 485 Nov 15 11:25 program
     $ program

    Takto nastevený skript by měl mít na začátku „magický“ komentář, který říká, jaký program by měl skript interpretovat. A tobuď s absolutní cestou k programu:

    #!/bin/bash
    #
    echo 'Hello World'

    Nebo, kvůli lepší přenositelnosti, pomocí env:

    #!/usr/bin/env bash
    #
    echo 'Hello World'

    Tento „magický“ komentář musí být vždy na první řádce skriptu!

Proměnné shellu

Proměnné v shellu jsou jen řetězce znaků, tj. i třeba číslo 10 je jen řetězec znaků "1" a "0". Proměnné se proto nemusí deklarovat (všechny jsou jednoho typu) - deklarují se tím, že se jim přiřadí hodnota.

EXAMPLES

jmeno=ret
jmeno je jméno proměnné, ret je řetězec znaků (=Praha,=,=1). Jméno může obsahovat libovolnou posloupnost znaků, kromě znaků mezera, tabulátor, nový řádek a $).
jmeno="ret ret"
vyskytuje-li se v retezci mezera ci metaznak, musi se retezec uzavrit do uvozovek.
jmeno=$jmeno2
promenne jmeno je prirazena stejna hodnota, jako je v promenne jmeno2

Význam uvozovek

'..'(apostrofy)
Potlaci specialni vyznam vsech znaku v retezci.
".."(uvozovky)
Potlaci specialni vyznam vsech znaku v retezci, ovsem pritom je mezi uvozovkami respektovana substituce priznaku (viz. zpetene apostrovy) a substituce promennych.
`..`
Priradi do promenne vystup prikazu.
adr=`pwd` do promenne adr priradi retez obsahujici jmeno pracovniho adresare.

Další práce s proměnnými

unset jmeno
zruší proměnnou zadaného jména
$jmeno
hodnota promenne jmeno
readonly jmeno
promenna jmeno
Promenna bude jen pro cteni. Pokusime-li se ji zmenit, shell zobrazi chybove hlaseni.
readonly
Bez argumentu zobrazuje seznam promennych jen pro cteni.

EXAMPLES

$ jmeno=`pwd`
$ echo $jmeno
/home/petr
$ readonly jmeno
$ jmeno=`pwd`
-bash: jmeno: proměnná pouze pro čtení

Argumenty příkazové řádky (poziční parametry)

$0
promenna obsahujici jmeno spusteneho souboru
$1
prvni z 9 argumentu uvedenych na prikazovem radku ($1..$9)
$#
pocet argumentu uvedenych v prikazovem radku
$*
reprezentuje vsechny argumenty. "$*" je ekvival. "$1 $2 ..."
$@
reprezentuje vsechny argumenty. "$@" je ekvival. "$1" "$2" ...

Pokud ma soubor vice jak devet argumentu, neda se k nim pristupovat primo. Muzeme se vsak pouzit prikaz shift. Timto prikazem se ze druheho argumentu stane prvni (je reprezentovan promennou $1), ze tretiho druhy atd. Soucasne se hodnota $# snizi o 1. Hodnota prvniho argumentu je ztracena.

Vyhrazená jména - vnitřní proměnné shellu

Promenne je mozno menit z prikazoveho radku, nebo v souboru ~/.profile, resp. ~/.bashrc. Nastavuji se prirazenim 'promenna=hodnota' (ovsem jen pro bash).

Příkaz export promenná=hodnota zajistí, že se nastavená proměnná předává i do skriptů a programů, které se z bashe spouštějí.

Proměnné se speciálním významem

CDPATH
Adresáře uložené v této proměnné (jako absolutní cesty) prohledává program cd, pokud zadáte relativní cestu k adresáři.
$ CDPATH=".:~:/var/run/media/petr/401194f3-6c11-4567-98ab-63ba02e87d89/petr/public_html/www/"
$ cd ~
$ pwd
/home/petr
$ cd nette
/var/run/media/petr/401194f3-6c11-4567-98ab-63ba02e87d89/petr/public_html/www/nette
IFS
definuje oddelovace argumentu prikazovaeho radku, standardne to jsou mezera, tabulator a znak noveho radku.
LOGNAME
prihlasovaci jmeno uzivatele
MAIL
jmeno souboru, ve kterem je ulozena elektronicka posta.
MAILCHECK
po kolika vterinach basch zjistuje doslou postu.
MAILPATH
obsahuje seznam jmen souboru s emaily oddelene dvojteckou
PATH
urcuje cesty k adresarum, kde ma iterpret hledat prikazy. Implicitne je PATH=:/bin:/usr/bin:. tzn. adresar /bin, adresar /usr/bin a aktualni adresar.
Doporucuji do PATH pridat jeste ~/bin/ a do tohoto adresare ukladat vlastni skripty:
$ PATH=$PATH:~/.bin
TERM
definuje typ pouziteho terminalu.
EDITOR
Standardni textovy editor, ktery je automaticky spusten nekterymi programi.
HISTSIZE
pocet prikazu, ktere se uchovavaji v prikazove historii.
HISTFILE
jmeno souboru, do nehoz se zapisuje prikazova historie (~/.bash_history
HISTFILESIZE
maximalni pocet radek obsazeny v souboru pro prikazovou historii
PS1

Prompt. Muze obsahovat nektere spec. sekvence, jejichz vyznam je tento:

\t	presny cas ve formatu HH:MM:SS
\d	datum, napr. `Sun Oct 2'
\n	prechod na novou radku
\s	jmeno ulity, tj. vetsinou 'bash'
\w	aktualni adresar (kompletni cesta)
\W 	aktualni adresar (bez cesty)
\u	jmeno aktualniho uzivatele
\h	jmeno PC
\#	poradi prikazu od spusteni ulity
\!	poradi prikazu v prikazove historii
\$	zobrazi $ pro bezneho uzivatele a # pro superuzivatele
\nnn	znak, jehoz osmickovy ASCII kod je nnn
\\	obracene lomitko
$ PS1='\h:\w\$ '
sallyx:~$
PS2
sekundarni prompt, kterym nas shell vyziva, abychom dokoncili prikaz, ktery zacal na jine radce

Nektere z promennych nastavuje automaticky operacni system a obvykle neni dobre je menit. Jsou to napr:

HOME
domaci adresar aktualniho uzivatele.
HOSTTYPE
retezec jednoznacne urcujici typ PC, na kterem bash bezi (i386).
PWD
aktualni adresar
OLDPWD
Predchozi pracovni adresar
RANDOM
generator nahodnych cisel v rozmezi 0 - 32767(i vice)
TZ=zzzX[ddd]
TZ urcuje casove pasmo. Tuto promennou nastavuje root.
zzz je jmeno pasma, X je casovy rozdil v hodinach vzhledem k GMT, ddd je jmeno mistniho casoveho pasma pro zmenu casu.

Proměnné aktualizované dle stavu procesu

?
navratovy kod posledniho provedeneho prikazu. 0 vetsinou znamena uspesne ukonceni, cislo pak cislo chyby.
#
pocet pozicnich prarametru prikazove procedury
*
obsah prikazove radky procedury, ktera je provadena.
$
PID aktualne beziciho shellu.
!
PID posledniho procesu spousteneho na pozadi
$ ls /nesmysl
/usr/bin/ls: nelze přistoupit k /nesmysl: Adresář nebo soubor neexistuje
$ echo $?
2
$ ls /home/
lost+found  petr  robotZaloha
$ echo $?
0
$ echo $$
30985

Navratovy kod posledniho provedeneho prikazu je ulozen v promenne ? a proces jej vraci svemu rodicovskemu procesu.
0 znamena, ze prikaz skoncil uspesne, jinak neuspesne.
Navratovy kod muzeme specifikovat pomoci prikazu exit, ktery ukonci vykonavani prikazoveho souboru.

Prostředí a exportování proměnných

. sript.sh

(tecka) vykona skript jako soucast aktualniho procesu a pracuje s promennymi rodicovskeho procesu. Zmeni-li nejakou promennou, pri skonceni dostane rodicovsky proces tuto promennou s novou hodnotu.
Hodnota promenne $0 je i pri provadeni detskeho procesu jmeno rodice!

Soubor id2s.h nemusi mit nastaveno pravo pro spousteni. Muze vypadat treba takto:
#!/usr/bin/env bash
echo id2.sh:PID=$$
$ echo $0 PID=$$
bash PID=30985
$ . id2.sh
id2.sh:PID=30985
$ chmod +x id2.sh
$ ./id2.sh
id2.sh:PID=32273
source skript.txt
provedou se prikazy souboru. totez co "tecka" viz vise
exec skript

puvodni proces je prekrit novym procesem a do puvodniho procesu se uz nemuze nikdy vratit. Prikaz exec vyzaduje, aby soubor mel prideleno pravo spusteni.

echo $0 PID=$$
exec id2
echo Tento text se uz nezobrazi

Soubor je take mozno spustit jen pouzitim jeho jmena (bez tecky ci prikazu exec). Takto spusteny proces ovsem neprejme deklarovane promenne od sveho rodice, ktere nebyli definovany s pouzitim prikazu export.

$ cat zmena.sh
echo $0 $$ $jazyk
jazyk=cestina
echo $0 $$ $jazyk
$ cat extest.sh
jazyk=anglictina
echo $0 $$ $jazyk
zmena.sh
echo $0 $$ $jazyk
$ extest.sh
./extest.sh 32519 anglictina
./zmena.sh 32520
./zmena.sh 32520 cestina
./extest.sh 32519 anglictina
$ cat extest1.sh
export jazyk
jazyk=anglictina
echo $0 $$ $jazyk
zmena.sh
echo $0 $$ $jazyk
$ extest1
./extest1.sh 32537 anglictina
./zmena.sh 32538 anglictina
./zmena.sh 32538 cestina
./extest1.sh 32537 anglictina
$ cat extest2.sh
jazyk=anglictina
echo $0 $$ $jazyk
. zmena.sh
echo $0 $$ $jazyk
$ extest2
./extest2.sh 32553 anglictina
./extest2.sh 32553 anglictina
./extest2.sh 32553 cestina
./extest2.sh 32553 cestina

Vstup z terminálu a z výstupu skriptu

Příkaz read

Příkaz read načte do proměnné řádek zadaný uživatelem

SYNOPSIS

read jmeno_promenne [jmeno promenne ...]

Je-li na radku vice promennych, do prvnich promenych se nacte vzdy jedno slovo a do posledni promenne se nactou zbyvajici slova z radky.

Zadanim $jmeno na prikazove radce bude hodnota v promenne jmeno interpretovana jako prikaz.

#!/usr/bin/env bash
echo Zadej povel
read povel
$povel
echo Konec povelu.

Přesměrování <<

Přesměrování << je presmerovani standardniho vstupu na cast textu prikazove procedury. Oddelovac je libovolný znak/řetězec za <<. Vstupní text musí být ukončen oddělovačem na samostatném řádku.

SYNOPSIS

prikaz <<oddelovac 
    ... vstupni radky ... 
oddelovac

EXAMPLE

V tomto pripade je oddelovac ! (vykřičník):

#!/usr/bin/env bash
mail $1 <<?php ?><!
        Prosim zavolejte mi na..
!
echo Zprava odeslana uzivateli $1
$ cat ed_program.sh
#!/usr/bin/env bash
ed $3 <<EOF
g/$1/s//$2/g
w
q
EOF

$ ed_program.sh unix UNIX soubor.txt

Tento priklad meni v souboru soubor.txt vsechny vyskyty retezce unix na retezec UNIX. V tomto pripade je oddelovacem retezec EOF. Shell odesila vse, co je mezi dvema oddelovaci, jako standardni vstup danemu procesu. Muzeme to chapat tak, ze jsme presmerovali standardni vstup do editoru ze souboru, ale tento soubor je uvnitr samotneho skriptu.

Oddělování a sdružování příkazů

Shellu musime nejak zdelit, kde konci jeden prikaz a zacina druhy. Jednim z oddelovacu je znak "novy_radek", tj. <Enter>. Ekvivalentni vyznam ma strednik ;.

Příkaz $a; b; c je totožný s příkazy:
$a
$b
$c

Dalsi „oddelovac“ je kanal (pipe) |

a|b|c
spusti prikaz a, jeho vystup preda prikazu b atd. Po skonceni vsech prikazu dostaneme zpet prompt.

Dalsim oddelovacem je symbol ulohy bezici na pozadi ampersand &.

a&b&c
vykona ulohy a a b na pozadi a c na popredi. Prompt dostaneme po vykonani ulohy c (ktera muze skoncit drive nez a nebo i b.
a&b&c&
vsechny ulohy bezi na pozadi a prompt dostaneme ihned.
a|b|c&
vsechny ulohy jsou spusteny jako jedna na pozadi. Prompt dostaneme okamzite.
(a;b)&c
zavorky zdruzuji prikazy tak, ze je shell chape jako jednu skupinu prikazu, se kterou zachazi jako s jednou ulohou. Prikazy a a b se vykonaji postupne na pozadi, zatimco prikaz c pobezi na popredi.
(a;b)&(c;d)&
postupne se vykonaji prikazy a a b na pozadi a soucasne se na pozadi budou postupne vykonavat prikazy c a d. Prompt obdrzime okamzite.

Existuji dve moznosti sdruzovani prikazu: pomoci obycejnych zavorek a pomoci slozenych zavorek. Obycejne zavorky rozdvoji puvodni shell, vykonaji se pozadovane prikazy a rizeni se vrati puvodnimu shellu. Pokud jsou prikazy sdruzeny pomoci slozenych zavorek {}, prikazy se vykonaji v ramci aktualniho shellu. Rozdil dokumentuji nasledujici priklady:

$ (pwd;cd /bin;pwd);pwd
/home/petr
/bin
/home/petr
$ { pwd;cd /bin;pwd;};pwd
/home/petr
/bin
/bin
První mezera a poslední ; v {} jsou nutné!
$ jazyk=cestina
$ (jazyk=anglictina)
$ echo $jazyk
cestina
$ { jazyk=anglictina;}
$ echo $jazyk
anglictina

Užitečné příkazy a programy pro skriptování

Příkaz set

Příkaz set bez zadaných argumentů vypíše všechny nastavené proměnné a definované funkce. Jinak se používá k definování proměnných.

SYNOPSIS

set [vyraz vyraz ...]

Přiřadí výrazy do proměnných $1, $2 ... (jako by šlo o argumenty příkazové řádky).

EXAMPLES

$ set `date`                              
$ echo $*                                
Ne čen 30 00:18:24 CEST 2013
$ echo "Argument 1: " $1                  
Argument 1:  Ne
$ echo "Argument 2: " $2                  
Argument 2:  čen
$ echo "Argument 3: " $3                  
Argument 3:  30
$ echo "Argument 4: " $4                  
Argument 4:  00:18:24
$ echo $2 $3, $6  
čen 30, 2013

Program sleep

Program sleep pozastaví běh skriptu na n sekund.

SYNOPSIS

sleep n

Příkaz exit

Příkaz exit ukončí skript. Rodičovskému shellu vrátí návratový kód zadaný jako argument příkazu exit.

SYNOPSIS

exit kod

Příkaz return

Příkaz return ukončí skript, nebo tělo funkce, aniž by to ukončilo shell. Rodičovskému shellu vrátí návratový kód zadaný jako argument příkazu return.

SYNOPSIS

return kod

Příkaz xargs

Vytvoří a spustí příkaz z řádků načtených ze standardního vstupu.

SYNOPSIS

xargs [-0] [-I replace-str] [command [initial-arguments]]

OPTIONS

-0
Řádek není ukončen bílým znakem (mezerou), ale nulovým znakem. (Odpovídá argumentu -print0 programu find, viz EXAMPLES)
-I replace-str
V textu command bude replace-str nahrazen zpracovávanou řádkou. (V EXAMPLES je replace-str {}).
command
Příkaz, který se vytvoří pro každou načtenou řádku.

EXAMPLES

$ find . -name "*.png" -print0 \
 | xargs -0 -I{} echo convert \"{}\" \"{}\" \
 | sed s/png/jpg/2
convert "./TreeOfLife.png" "./TreeOfLife.jpg"
convert "./Boobs.png" "./Boobs.jpg"

Program dialog

Tento program se dá použít na vytvoření různých grafických dialogů.

EXAMPLES

dialog --msgbox "Message dialog" 10 40`
dialog --fselect /usr/bin 0 0
dialog --calendar "When is your birthday this year?" 0 0 14 05 2018
dialog --passwordbox "Please enter your password." 0 0
dialog --checklist "Please select your value" 0 0 0 "1)" "First Option" "on" "2)" "Second Option" "off"
dialog --menu "Please select an option" 0 0 0 "1)" "First Option" "2)" "Second" "3)" "Third"
for i in $(seq 0 10 100)
do
echo $i | dialog --gauge "Please wait" 10 70 0;
sleep 1;
done
Komentář Hlášení chyby
Created: 11.9.2005
Last updated: 24.1.2018
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..