View on GitHub

Практикум из рачунарских алата

ОЕ1-ПРА

ПРА: Linux скриптовање - белешке са вежби


Садржаји су углавном преузети из књиге TLCL, биће назначено о којој се области ради. Биће излистани одабрани садржаји са примерима ради лакше навигације.


Манипулација називима датотека


Област 4 - Wildcards && Област 7 - Pathname expansion


Примери
echo * # излистава све датотеке које се налазе у тренутном радном директоријуму
echo [abc]* # излистава све датотеке које се налазе у тренутном радном директоријуму и чији назив почиње или малим словом "a", или "b", или "c" 
echo primer?.txt # излистава све датотеке које се налазе у тренутном радном директоријуму и које у свом називу имају реч primer праћену тачно једним карактером (рецимо број, нумерација; али може бити било који други карактер), а потом и екстензију (суфикс) .txt
echo primer[0-9].txt # излистава све датотеке које се налазе у тренутном радном директоријуму и које у свом називу имају реч primer праћену тачно једним бројем, а потом и суфиксом .txt
echo [[:upper:]]* # излистава све датотеке које се налазе у тренутном радном директоријуму и чији назив почиње великим словом


Област 7 - Brace expansion

На место означено витичастим заградама убацити више различитих вредности, дефинисаних задатим скупом/опсегом.


Пример
mkdir -p proba/godina_{1926..2026}/mesec_{jan,feb,mar}/nedelja_{1..4} 


Проширење (eкспанзија) специјалним карактером $


Област 7 - Arithmetic expansion


Пример
echo $(($((5**2)) * 3)) # 75


Област 7 - Parameter expansion


Пример
echo $USER # враћа ваше корисничко име


Област 7 - Command substitution


Пример
CURRENT_DIR=$(pwd) # унутар променљиве је смештена путања до директоријума у ком се тренутно налази корисник


Избегавање (escape) специјалних карактера


Област 7 - Quoting


До сада је виђен велики број карактера који имају посебно значење зависно од случаја употребе. Некада је неопходно ипак занемарити та специјална значењa. Такозвано избегавање (escape) се може постићи на више начина:


Примери
mkdir Moj Direktorijum
mkdir Moj\ Direktorijum
mkdir "Moj Direktorijum"
mkdir 'Moj Direktorijum'


echo text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
echo "text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER"
echo 'text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER'

Регуларни изрази


Област 19 - Regular Expressions


Превасходно се користе за манипулациjу текстуалног садржаjа, и интегрисани су у наредбу grep, коjа се користи за претрагу садржаjа датотека. Могуће jе регуларне изразе користити и за претрагу путања до датотека или директоријума, у комбинациjи са функциjом find.


Примери
grep -i '^..j.r$' /usr/share/dict/words # за хипотетичке укрштенице, тражи речи садржане у речнику, такве да имају 5 слова, од којих је познато треће слово "j", и последње слово "r".


mkdir -p vezbanje/tes{t,T}
ls ./vezbanje/ > proba.txt
grep '[A-Z]$' proba.txt 
find ./vezbanje/ -type d -regex '.*[A-Z]$'
# ово тражи директоријуме чији се назив завршава великим словом
# уочити да је за позив наредбе find неопходно експлицитно нагласити да се употребљава регуларни израз
# уједно је код find наредбе неопходно уклопити цео стринг у регуларни израз, а не само произвољни подстринг
# уочити да наредба find враћа читаву путању до жељене датотеке


Постоји више различитих дијалеката регуларних израза, односно начина на који се “чита” написани шаблон регуларног израза. Наредба grep подразумевано користи Basic Regular Expressions (BRE) дијалекат. Међутим, постоји додатан сет специјалних карактера за регуларне изразе који је могуће користити у оквиру Extended Regular Expressions (ERE) дијалекта. И BRE и ERE су усклађени са POSIX стандардом. Да би наредба grep користила дијалекат ERE потребно је додати заставицу (флег) -E (или алтернативно позвати функцију egrep). Наредба find за претрагу датотечног система подразумевано користи дијалекат Emacs стила за регуларне изразе који није усклађен са POSIX стандардом као што су BRE и ERE дијалекти. Да би и наредба find користила ERE дијалекат, потребно је специфицирати опцију -regextype posix-extended (заједно са -regex "pattern"). Додатни специјали карактери доступни у оквиру Extended Regular Expressions (ERE) дијалекта су:


Примери
echo "(555) 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$'
echo "555 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$'
echo "5555 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$'
# заграде код "позивног" броја су опционе, он се састоји из тачно 3 цифре, што је праћено са још 3 цифре, -, и на крају још 4 цифре


echo "AAA" | grep -E 'AAA|BBB'
echo "BBB" | grep -E 'AAA|BBB'
echo "CCC" | grep -E 'AAA|BBB'


mkdir -p vezbanje/test_{1..6}
ls ./vezbanje/ > proba.txt
grep -E '(test_1|test_3|test_5)' proba.txt 




Скриптовање


Гранање


Област 27 - Branching with if

Синтакса за употребу гранања (псеудокод):


if услов_1; then
    први
    блок
    наредби
elif услов_2; then
    други
    блок
    наредби
else
    последњи
    блок
    наредби
fi # не заборавити ово за затварање!


Наведени услови се евалуирају конверзијом у True или False, тако што се имплицитно врши позив наредбе test.


test expression
#или
[ expression ]


# конкретно пример провере једнакости вредности променљиве X и целобројне вредности 5
if [ "$x" -eq 5 ]; then ...


Тестови који се извршавају над датотекама:


Пример
#!/bin/bash
# test-file: Evaluate the status of a file
FILE=~/.bashrc
if [ -e "$FILE" ]; then
    if [ -f "$FILE" ]; then
    echo "$FILE is a regular file."
    fi
    if [ -d "$FILE" ]; then
    echo "$FILE is a directory."
    fi
    if [ -r "$FILE" ]; then
    echo "$FILE is readable."
    fi
    if [ -w "$FILE" ]; then
    echo "$FILE is writable."
    fi
    if [ -x "$FILE" ]; then
    echo "$FILE is executable/searchable."
    fi
else
    echo "$FILE does not exist"
    exit 1
fi
exit


Тестови који се извршавају над стринговима:


Пример
#!/bin/bash
# test-string: evaluate the value of a string
ANSWER=maybe
if [ -z "$ANSWER" ]; then
    echo "There is no answer." >&2
    exit 1
fi
if [ "$ANSWER" == "yes" ]; then
    echo "The answer is YES."
elif [ "$ANSWER" == "no" ]; then
    echo "The answer is NO."
elif [ "$ANSWER" == "maybe" ]; then
    echo "The answer is MAYBE."
else
    echo "The answer is UNKNOWN."
fi


Тестови који се извршавају над целобројним вредностима:


Пример
#!/bin/bash
# test-integer: evaluate the value of an integer.
INT=-5
if [ -z "$INT" ]; then
    echo "INT is empty." >&2
    exit 1
fi
if [ "$INT" -eq 0 ]; then
    echo "INT is zero."
else
    if [ "$INT" -lt 0 ]; then
        echo "INT is negative."
    else
        echo "INT is positive."
    fi
    if [ $((INT % 2)) -eq 0 ]; then
        echo "INT is even."
    else
        echo "INT is odd."
    fi
fi


Постоје две модификације наредбе test, једна за рад конкретно са целобројним вредностима, а друга која дозвољава и проверу стрингова употребом регуларних израза:

(( expression )) # за рад са бројевима

[[ expression ]] # проширење које подржава регуларне изразе


Пример
#!/bin/bash
# test-integer2a: evaluate the value of an integer.
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then # - као предзнак је опциони, и праћен је низом цифара
    if ((INT == 0)); then # уочити да се вредности променљивих унутар (()) директно евалуирају без употребе $
        echo "INT is zero."
    else
        if ((INT < 0)); then
            echo "INT is negative."
        else
            echo "INT is positive."
        fi
        if (( ((INT % 2)) == 0)); then
            echo "INT is even."
        else
            echo "INT is odd."
        fi
    fi
else
    echo "INT is not an integer." >&2
    exit 1
fi


Могуће је комбиновати резултате евалуације услова коришћењем следећих оператора:


Пример
#!/bin/bash
# test-integer3: determine if an integer is within a
# specified range of values.
MIN_VAL=1
MAX_VAL=100
INT=50
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
    if [[ "$INT" -ge "$MIN_VAL" && "$INT" -le "$MAX_VAL" ]]; then
#   if [ "$INT" -ge "$MIN_VAL" -a "$INT" -le "$MAX_VAL" ]; then        # алтернативно
#   if (( ((INT >= MIN_VAL)) && ((INT <= MAX_VAL)) )); then            # алтернативно
        echo "$INT is within $MIN_VAL to $MAX_VAL."
    else
        echo "$INT is out of range."
    fi
else
    echo "INT is not an integer." >&2
    exit 1
fi


Уједно се у оквиру области 27 налази секција о операторима контроле тока (Flow Control) - други начин за гранање. Конкретно, за овај вид гранања се користе оператори AND и OR:

Могуће је произвољно много наредби спрегнути помоћу поменутих команди.


Примери
 mkdir temp && cd temp # идеја је да се направи нови директоријум, а потом и да се у њега пређе
 # прво се извршава команда за прављење новог директоријума
 # прелазак у нови директоријум ће се десити акко је успешно направљен поменути директоријум


[[ -d temp ]] || mkdir temp # идеја је проверити да ли већ постоји директоријум који је потребно направити
# прво се извршава провера
# прављење директоријума ће се десити акко се провера да ли он већ постоји евалуира као False


[[ -d $NEW_DIR ]] && echo $NEW_DIR already exists, aborting && exit
mkdir $NEW_DIR
# прво се извршава провера постојања директоријума са истим називом као онај који треба направити
# уколико такав директоријум НЕ постоји, даље наведене наредбе (у десно) се не извршавају, односно прелази се на нови ред
# уколико такав директоријум заиста постоји, извршава се следећа наредба (еcho)
# уколико се позив echo наредбе успешно изврши, извршава се и наредба exit



Switch - case


Конструкција switch-case подразумева тражење поклапања вредности неке променљиве са једним од понуђених калупа (образаца). Користи се сет специјалних карактера описан у првом поглављу. Синтакса је следећег облика (псеудокод):

case "@реч" in
    образац_1) први
               блок
               наредби
               ;; #& опционо
    образац_2) други
               блок
               наредби
               ;; #& опционо
      .
      .
      .
    образац_N) последњи
               блок
               наредби
               ;; #& опционо
    *)  echo "Лош унос!" 
        exit 1
esac # затварање case-а!
Примери
#!/bin/bash
rec="нека_реч"
case "$rec" in
    [[:alpha:]])
    echo "Реч се састоји из тачно једног словног карактера." ;;
    [ABC][0-9])
    echo "Реч се састоји из A или B или C карактера, праћено цифром." ;;
    ???)
    echo "Реч се састоји од 3 карактера." ;;
    *.txt)
    echo "Реч се завршава са '.txt'." ;;
    *)
    echo "Реч је нешто друго." ;;
esac


#!/bin/bash
karakter="A"
case "$karakter" in
    [[:upper:]])
    echo "'$karakter' је велико слово." ;;&
    [[:lower:]])
    echo "'$karakter' је мало слово." ;;&
    [[:alpha:]])
    echo "'$karakter' је слово." ;;&
    [[:digit:]])
    echo "'$karakter' је цифра." ;;&
    [[:space:]])
    echo "'$karakter' је space." ;;&
esac



Кориснички унос


Два приступа - тражење корисничког уноса унутар саме скрипте, или употреба позиционих параметара дефинисаних при позиву скрипте (Област 32).


Пример
#!/bin/bash
# pp.sh: script to view command line parameters
echo "
Number of arguments: $#
\$0 = $0
\$1 = $1
\$2 = $2
\$3 = $3
\$4 = $4
\$5 = $5
\$6 = $6
\$7 = $7
\$8 = $8
\$9 = $9
"
shift

echo "
After shift
Number of arguments: $#
\$0 = $0
\$1 = $1
\$2 = $2
\$3 = $3
\$4 = $4
\$5 = $5
\$6 = $6
\$7 = $7
\$8 = $8
\$9 = $9
"


./pp.sh a b c d


Number of arguments: 4
$0 = ./pp.sh
$1 = a
$2 = b
$3 = c
$4 = d
$5 = 
$6 = 
$7 = 
$8 = 
$9 = 


After shift
Number of arguments: 3
$0 = ./pp.sh
$1 = b
$2 = c
$3 = d
$4 = 
$5 = 
$6 = 
$7 = 
$8 = 
$9 = 


For петља


Област 33 - Looping with for

Синтакса за употребу for петље:


for i in iterable; do
#for i in $@: do         # рецимо
#for i; do               # исто као ово изнад, ако се не наведе експлицитно по чему се итерира, подразумевају се позициони параметри
    блок
    наредби
    у петљи
done # не заборавити ово за затварање!


# или, aко сте користили већ C

for (( i=0; i<5; i=i+1 )); do
    echo $i # нпр само прост бројач
done