Sciptování


Zde je popis regulárních výrazů a scriptovacího jazyka bash

OBSAH


Regulární výrazy
Bash


Regulární výrazy




jsou to znaky které pomáhají definovat skupinu znaků, které mají určité vlasnosti.Díky nim můžeme výběr omezit na slovo na konci řádku, nebo najít slovo, které začíná na m, má 8 znaků a poslední znak je třeba f (smirnoff)
POZOR-shel expanduje znaky, proto je dobrý dát celý výraz do uvozovek viz-grep telef "( on | ax )" text.txt
[] jeden z těchto znaků
[1-4] znamená čísla 1 až 4
[D,Z] znamená písmena D a Z
[123] Množina číslic 1, 2 a 3.
b[au]f Odpovídá řetězci baf nebo buf.
[a-zA-Z] nebo [\w ] Množina rozsahu znaků. Odpovídá jednomu výskytu písmene A až Z (malá i velká písmena, pouze bez diakritiky).
[[:alpha:]] Totéž, ale zahrnuje i písmena s háčky a čárkami (pokud jsou nastavené české locales).
[[:alnum:]] Jako předchozí, ale navíc zahrnuje číslice.
[0-9] nebo [[:digit:]] nebo [\d] Množina všech číslic.
[^0-9] nebo [^[:digit:]] nebo [^\d] nebo [\D] Odpovídá jednomu znaku, který není číslice
[[:space:]] Množina "whitespace" znaků
() gruping, neboli co je v této závorce se bude brát jako jeden řetězec
(ahoj|cau) znamená slovo ahoj nebo cau
| nebo
^ označuje začátek řádku
$ označuje konec řádku
\< začátek slova
\> konec slova
.. (2x tečka) označuje nasledujíci metacharakter ( třeba ,[,] )
. (1x tečka) Množina všech znaků. Odpovídá jednomu znaku.
* označuje vyskyt 0 až nekonečně jakéhokoliv znaku
+ označuje výskyt aspon 1x až nekonečně
? označuje výskyt 1 nebo 0
{n} "" "" označuje výskyt prave n-krat
{n,} "" "" označuje výskyt nejméně n-krat
{n,m} "" "" označuje výskyt nejméně n-krat, nejvice m-krat
\t tabulátor
\n nový řádek
\. Odpovídá tečce.
\\ Odpovídá zpětnému lomítku.
\* Odpovídá hvězdičce.

Bash




instalace
/usr/ports/shells/bash
make install


nastaveni bashe jako vychozi shell
chsh -s /usr/local/bin/bash user


cesta ke shelu bash
#!/usr/local/bin/bash

pripadne udelat zastupce pro spouštění bash scriptů bez úpravy hlavičky
ln -s /usr/local/bin/bash /bin/bash

můžeme se z aktuálního shelu přepnout do bashe třeba jen na chvíli,udělat co potřebujem a vrátit se zpět

přepnutí do bash
bash
zpět
exit

přepnutí do sh
sh
zpět
return


jednoduchý příkazy
> presmerovani vystupu
ps > text.txt

< vlozeni do programu
mysql < zaloha.sql

>> pripoji vystup na konec souboru
ps >> text.txt

2 > &1 nasmerovani dvou vystupu do jednoho souboru
kill -l 1234 > kill.txt 2 > &1
vstup (stdin (0) ) a výstup (stdout (1) ) jsou přesměrovány do jednoho výstupu
vstup může být příkaz zadaný z klávesnice, nebo výsledek jiného procesu
výstup je většinou výsledek příkazu či procesu, zobrazený na obrazovce, vytištěný na tiskárně, uložený do souboru nebo předaný dalšímu procesu ke zpracování
chybový výstup (stderr (2) )-do tohoto výstupu jdou chyby, nechá se přesměrovat třeba do souboru, nebo využít v podmínkách


/dev/null přesměrovaní pro smazani výstupu,nebo smazani souboru
kill -l 1234 > /dev/null
soubor.txt > /dev/null

| roura /pipe ,předáva výsledek programu jinému programu
ps -ax | more

#!/bin/sh začátek každého scriptu

# komentar


testtestování na podmínky

if test -f /etc/foo

se dá také zapsat takto:

if [ -f /etc/foo ]; then


Možnosti příkazu test
testy souborů/adresářů
-e soubor existuje
-f soubor je standardní (tzn. není to ani adresář ani speciální soubor)
-s soubor má nenulovou velikost
-d soubor je adresář
-b soubor je speciální blokové zařízení
-c soubor je speciální znakové zařízení
-p soubor je roura (pipe)
-h soubor je symbolický link
-L soubor je symbolický link
-S soubor je socket
-t soubor je deskriptor
-r soubor má práva pro čtení (pro uživatele, který spustil daný test)
-w soubor má právo zápisu (pro uživatele, který spustil daný test)
-x soubor je spustitelný (pro uživatele, který spustil daný test)
-g soubor má nastaven SGID bit
-u soubor má nastaven SUID bit
-k soubor má nastaven sticky bit
-O jsme vlastníkem souboru
-G group ID souboru je stejná jako naše
-N soubor byl modifikován od posledního načtení
f1 -nt f2 souborf1 je novější než soubor f2
f1 -ot f2 souborf1 je starší než soubor f2
f1 -ef f2 souborf1 a f2 je hard link na jeden a tentýž soubor
! obrací logiku testů


#####################

IFS='' #interni oddělovač poli{jakym znakem budou oddeleny jednotlive pole-uzavírá se do apostrofů-zde je to mezera}
set A B C #nastaveni parametru/poli
echo $@ #volaní fce echo
ABC #výsledek

unset IFS #zrusení IFS
echo $@ #volaní fce echo
A B C #výsledek

########################


Proměnné
proměnnou může být číslo, slovo, výraz, případně i příkaz nebo jiná proměnná
POZOR-u přiřazení promenna=hodnota nesmí být u rovnítka mezera

proměnnou definujeme názvem a hodnotou
nazev=hodnota

proměnnou voláme tak, že před název proměnné dáme znak $

příklad
cislo=5
den="patek"
datum=`date "+%Y-%m-%d" ` # pozor -příkazy uzavíráme do ``(na angl klávesnici pod ESC)
date=$datum


volání proměnné
echo $datum

zvláštním případem jsou systémové proměnné
$? - obsahuje návratový kód posledního procesu spuštěného na popředí.
$$ - obsahuje pid aktuálního procesu (ať víte co zabíjet :-)
$0 - obsahuje jméno právě prováděného skriptu: mujskript
$1 - obsahuje první argument, předaný skriptu, na příkazové řádce: parametr1
$9 - obsahuje 9-tý argument z příkazové řádky: parametr9
$* - obsahuje všechny argumenty volání programu (jako jedno slovo): parametr1 parametr2 ... parametrn
$@ - obsahuje všechny argumenty volání programu (jednotlivá slova): parametr1 parametr2 ... parametrn
$# - obsahuje počet argumentů z příkazové řádky (v našem případě n).

dalšími proměnnými je systémové prostředí
Vypíšeme jej příkazem set
Výpis proměnných v bashi

BASH=/bin/bash
BASH_ARGC=()
BASH_ARGV=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="3" [1]="2" [2]="39" [3]="1" [4]="release" [5]="i386-portbld-freebsd6.3")
BASH_VERSION='3.2.39(1)-release'
BLOCKSIZE=K
COLUMNS=106
DIRSTACK=()
EDITOR=vi
ENV=/home/votruba/.shrc
EUID=0
FTP_PASSIVE_MODE=YES
GROUP=wheel
GROUPS=()
HISTFILE=/root/.bash_history
HISTFILESIZE=500
HISTSIZE=500
HOME=/root
HOST=test63.keytec.cz
HOSTNAME=test63.keytec.cz
HOSTTYPE=FreeBSD
IFS=$' \t\n'
LINES=63
LOGNAME=votruba
MACHTYPE=i386
MAIL=/var/mail/votruba
MAILCHECK=60
MC_SID=32322
MC_TMPDIR=/tmp/mc-root
OPTERR=1
OPTIND=1
OSTYPE=FreeBSD
PAGER=more
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin:/root/bin
PPID=32322
PS1='[\u@\h \w]\$ '
PS2='> '
PS4='+ '
PWD=/root/script
REMOTEHOST=192.168.0.92
SHELL=/bin/csh
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=3
SSH_CLIENT='192.168.0.92 1234 22'
SSH_CONNECTION='192.168.0.92 1234 192.168.0.5 22'
SSH_TTY=/dev/ttyp0
TERM=xterm
UID=0
USER=votruba
VENDOR=intel
_=bash



proměnné můžeme i vymazat

zapomene všechny proměnné
unset

zapomene proměnnou date
unset date

přidání proměnné nastálo
export PROMENNA=nova_promenna

přidání nové cesty do proměnné PATH
export PATH=$PATH:/dalsi/cesta/kde_hledat


Pole
Obsahem pole může být i jiné pole

pole můžeme naplnit 2mi způsoby

nadefinování pole
declare -a cesta

cesta[1]=path
cesta[2]=path2
cesta[3]=path3
cesta[4]=path4
cesta[5]=path5
cesta[6]=path6
cesta[7]=path7
cesta[8]=path8


nadefinování pole - druhá možnost

pole=( jedna dva tri ctyri pet )
v tomto případě má první položka pozici 0. Tj slovo "pet" ma pozici 4

echo ${pole[*]:0}
výsledek
jedna dva tri ctyri pet


výpis všech položek pole
echo ${cesta[*]} #NEBO ${pole[*]:0}
výsledek
path path2 path3 path4 path5 path6 path7 path8

výpis jedné položky pole
echo "${cesta[4]}"
výsledek
path4

výpis všech položek pole od daného čísla do konce(zde od 3)
echo "${cesta[*]:3}"
výsledek
path3 path4 path5 path6 path7 path8

výpis všech položek pole od daného čísla a k němu 2 následující
echo "${cesta[*]:3:2}"
výsledek
path3 path4

výpis všech položek pole s vynecháním nějaké položky ( zde definované reg. výrazem)
echo "${cesta[*]#*3}"
výsledek
path path2 path4 path5 path6 path7 path8


If #testuje podminky

if jestliže
PODMINKA
then potom proved´
PRIKAZY
else jesliže nevyhovi,pak proved
PRIKAZY
fi ukonceni

#####################
Elif #stejně jako IF ,ale pokud neni splněna prvni podmínka testuje druhou

if jestliže
PODMINKA
then potom proved´
PRIKAZY
elif nebo proved´
PRIKAZY
else jesliže nevyhoví,pak proved´
PRIKAZY
fi ukončeni

POZOR-v podmínce if [ vyraz ] musí být testovaný výraz oddělen mezerou od závorek [ ]

######################

For #vytvářeni cyklu ktere pracují s rozsahem hodnot-mohou být uvedeny v programu,nebo jako parametry názvu scriptu

for PROMENNA in HODNOTY pro kazdou promennou{promenna je to co je vyjadreno za IN,byva to nekolik hodnot oddelenych mezerou}
do proved´
PRIKAZY
done ukončeni

for DNY in PO UT ST CT PA SO NE
do
echo $DNY
done

PO
UT
ST.....
zde DNY jsou proměnnou a to co je za in (oddělené mezerami) je počet rotací


je možné na místě proměnné nadefinovat i pole
for inkr in ${uzivatel[*]}
do
......


v tomto případě cyklus bude rotovat tolikrát, kolik je v poli objektů. Pozor, pokud bude pole s 5 objekty a jednim z objektů bude další pole s 2mi položkami tak cyklus prorotuje 2(to vložené pole) + 4(zbytek objektů) tj 6x.

Klidně můžeme použít pro počet rotací nějaké pole, nebo výraz a v příkaze "do" provádět akci, která nemá s tím polem nic společného jen si z něj bere počet rotací.


našel jsem hezký příklad, kdy si příkaz v aktualním adresáři zjistí soubory .htm a následně je je přejmenuje na .html

for file in *.htm
do
echo "menim pripony .htm souboru $file... na .html"
mv $file.htm $file.html
done


Příkaz for se nechá použít i bez "in HODNOTA", pak se počet rotací zadá výrazem
např.
for (( a=1 ; $a-4 ; a=$a+1 ))
do echo $a
done



######################

While #prikaz ktery provadi prikaz pokud JE splnena podminka

while PODMINKA
do
PRIKAZY
done

V následujícím příkladu použijeme proměnnou x, která bude při každém průchodu cyklu zvyšovat svojí hodnotu a to až do té doby než dosáhne hodnoty 10.

#!/bin/bash
x=0; # inicializuje hodnotu x na 0
while [ $x -le 10 ]; do
echo "Aktuální hodnota x: $x"
x=$(expr $x + 1) # zvýšení hodnoty x o 1
sleep 1
done


Jak vidíte, používáme příkaz test (hranaté závorky), abychom zjistili, jestli hodnota proměnné x je menší nebo rovno 10. Je-li menší nebo rovno 10, test je vyhodnoceno jako true a blok příkazů za slovem do se může provést. Je-li však podmínka vyhodnocena jako false, pokračuje program v běhu za slovem done.

########################

Until #prikaz ktery provadi prikaz pokud NENI splnena podminka

until PODMINKA
do
PRIKAZY
done

#!/bin/bash
x=0
until [ "$x" -ge 10 ]; then
echo "Aktuální hodnota x: $x"
x=$(expr $x + 1)
sleep 1
done


Je použita struktura until a tedy příkaz test je upraven tak, aby byla struktura ukončena bude-li hodnota proměnné x větší nebo rovno 10. Znamená to tedy, že se vypíší hodnoty pouze od 0 do 9.

########################

Case #struktura case je určena pro vykonání jednoho z několika kusů kódu a to podle toho, jakou hodnotu má proměnná uvedená za příkazem case

case PROMENNA in
vzorek [ vzorek| vzorek] ....) PRIKAZY;; #kazdy vzorek musi byt ukoncen 2ma stredniky
vzorek [ | vzorek] ....) PRIKAZY;; # mezi vzorky je mozno vkladat vice prikazu
vzorek [ | vzorek] ....) PRIKAZY;;
...........
esac


#!/bin/bash

echo "Je nyní ráno? Odpovězte \"ano\" nebo \"ne\""
read timeofday # nacte uzivatelsky vstup

case "$timeofday" in #nacteni promenny
ano | a | Ano | ANO ) #pokud je kladna odpoved
echo "Dobré ráno" #vykona tento prikaz
;;
[nN]* ) #pokud je zaporna odpoved
echo "Dobré odpoledne" #vykona tento prikaz
;;
* ) #pokud je jina odpoved
echo "Promiňte, ale nerozuměl jsem" #vykona tento prikaz
echo "Odpovězte \"ano\" nebo \"ne\"" #vykona tento prikaz
exit 1
;;
esac #ukonceni prikazu

exit 0


########################
Seznamy
&& #logicke ANO-spojovani prikazu,nasledujici pokracuje jen po uspesnem vykonani predchazejiciho
#jinak skonci
PRIKAZ1 && PRIKAZ2 && PRIKAZ3 && PRIKAZ4 cd /root && touch test.sh && cp test.sh test2.sh


|| # logiske NEBO- prikaz jede z prava do leva dokud nektery z prikazu nevrati hodnoutu TRUE,pak skonci

PRIKAZ1 || PRIKAZ2 || PRIKAZ3 || PRIKAZ4



#!/bin/bash

rm -f file_one

if [ -f file_one ] || echo "hello" || echo "there"
then
echo -e "in if"
else
echo -e "in else"
fi

exit 0

Výstup programu bude následující:

xconsole$ ./skript.sh
hello
in if


########################


Funkce #Použití funkcí se vyplatí v případě, kdy se bloky kódu ve skriptu opakují.

function NAZEV_FUNKCE () #slovo *function* muzeme vynechat
{
PRIKAZY
}

NAZEV_FUNKCE #funkci zavolame zadanim jejiho nazvu-musi byt deklarovana pred zavolanim

#!/bin/bash

yes_or_no() {
echo "Je tvé jméno $* ?"
while true
do
echo -n "Napiš ano nebo ne: "
read x
case "$x" in
a | ano ) return 0;;
n | ne ) return 1;;
* ) echo "Napiš ano nebo ne"
esac
done
}

echo "Původní parametr je $*"

if yes_or_no "$1"
then
echo "Ahoj $1, pěkné jméno"
else
echo "Nikdy"
fi
exit 0


prispusteni tothoto scriptu se musi jako parametr zadat jmeno

Tento příklad funguje tak, že po spuštění skriptu je definována funkce yes_or_no, ale není provedena. V příkazu if provede skript funkci yes_or_no, které předá jako parametry zbytek řádku, kde zápis $1 nahradí prvním parametrem skriptu. Funkce pak pracuje s těmito parametry, které jsou nyní uloženy v pozičních proměnných $1, $2 atd. a vrátí hodnotu volajícímu příkazu. Příkaz if v závislosti na návratové hodnotě provede příslušní příkaz.

###################################

Příkazy

break #slouží k odskoku z cyklu for, while nebo until ještě před splněním řídicí podmínky nepouziva se
##
: #zastupuje hodnotu true
rm -rf fred
if [ -f fred ]; then
:
else
echo "Soubor fred neexistuje."
fi


##

continue #tento příkaz spustí další iteraci (průchod) cyklů for, while nebo until, přičemž je proměnné cyklu přiřazena další hodnota ze seznamu

#!/bin/bash

rm -rf fred*
echo > fred1
echo > fred2
mkdir fred 3
echo > fred4

for file in fred*
do
if [ -d "$file" ]; then
echo "přeskakuji adresář $file"
continue
fi
echo soubor je $file
done

rm -rf fred*
exit 0

##

. nebo Source #nacte externi soubor,vykona jej a vysledek vrati puvodnimu scriptu

##

eval #umožňuje vyhodnocovat argumenty

foo=10
x=foo
y='$'$x
echo $y

Tento skript vrátí $foo, ale následující

foo=10
x=foo
eval y='$'$x
echo $y

již vrátí 10. Tudíž příkaz eval funguje trochu jako další znak $ - vrátí hodnotu hodnoty proměnné.


##
exec # nahradí současný proces zadaným příkazem.

exec wall "Děkuji za všechny ryby"

ve skriptu nahradí aktuální shell příkazen wall. Řádky, které ve skriptu následují po příkazu exec, nebudou provedeny, protže shell, který skript prováděl, již neexistuje.

##
exit #ukončení skriptu s návratovým kódem n
exit 0 #navratova hodnota TRUE
exit 1 #navratova hodnota FALSE POKUD SE POUZIJE NEKDE VE SCRIPTU-SCRIPT SE UKONCI A DAL NEJEDE


##

Počet přístupů na stránky 1