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.
- 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 < programV takto spustenem skriptue se mohou vyuzivat argumenty z prikazove radky, program nemusi mit nastaveno pravo pro spusteni - x.
$ sh program -
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
$ programTakto 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
$ 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
- 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
/usr/bin/ls: nelze přistoupit k /nesmysl: Adresář nebo soubor neexistuje
$ echo $?
2
$ ls /home/
lost+found petr robotZaloha
$ echo $?
0
$ echo $$
30985
Návratové kody
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
.
echo $0 $$ $jazyk
jazyk=cestina
echo $0 $$ $jazyk
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
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
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.
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):
mail $1 <<?php ?><!
Prosim zavolejte mi na..
!
echo Zprava odeslana uzivateli $1
#!/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
ab
se vykonaji postupne na pozadi, zatimco prikazc
pobezi na popredi. - (a;b)&(c;d)&
-
postupne se vykonaji prikazy
a
ab
na pozadi a soucasne se na pozadi budou postupne vykonavat prikazyc
ad
. 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:
/home/petr
/bin
/home/petr
$ { pwd;cd /bin;pwd;};pwd
/home/petr
/bin
/bin
;
v {} jsou nutné!
$ (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
$ 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
| 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 --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