Systemy operacyjne

Opis zajęć i zasad

Zajęcia 6

Skrypty *

eval

Instrukcja eval służy do zbudowania komendy i jej wykonania przez powłokę.

Przykład:

t="echo ala ma kota"
eval $t

Poprzez zacytowanie znaków specjalnych eval może również korzystać ze zmiennych.

cz1="ala ma \$i koty"
cz2="i \$j psy"
i=3
j=2
echo $cz1
echo $cz2
eval echo $cz1 $cz2

Eval zbiera argumenty i konstruuje z nich komendę, najpierw ewaluując wartości argumentów. Spójrz na przykład

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

Przykład 2: Zapisz i wywołaj skrypt:

#!/bin/bash
#ls command stored in a variable
COMMAND="ls -lrt"
#executing the ls command using eval
eval $COMMAND

Eval zwraca kod (status) wykonania komendy

eval y=1
echo $?
eval "bzdury"
echo $?
eval ls --bzdury
echo $?

expr

Program expr służy do obliczania wartości arytmetycznych:

expr 80 \* 24
expr 15 / 4 # całkowita wartosc dzielenia (ucinanie wartosci, zamiast 3.75 mamy 3)
expr 15 % 4 # reszta z dzielenia
NUM=0
expr $NUM + 1 # suma
expr $NUM - 1 # różnica
NUM=5
PREV=6
expr $NUM = $PREV       # nie równe to 0
expr $NUM = $NUM        # nie równe to 0
expr $NUM \> $PREV      # większe równe itd.
                        # arg1 \>= arg2 Displays a 1 if arg1 is greater than or equal to arg2.
                        # arg1 \< arg2  Displays a 1 if arg1 is less than arg2.
                        # arg1 \<= arg2 Displays a 1 if arg1 is less than or equal to arg2.
                        # arg1 !> arg2  Displays a 1 if arg1 is not equal to arg2.
VAR=""  # Set VAR to NUL
PRT=""  # Set PRT to NUL
expr $VAR \& $PRT       # Zwraca wartosc arg1 jeżeli arg1 oraz arg2 nie są 0 lub NUL; w przeciwnym wypadku zwraca, 0.
VAR="hplj"
PRT="hpij"
expr $VAR \& $PRT       # zwraca wartosc VAR

Expr możemy wykorzystywac także do porównywania ciagów znakowych.

expr string : str       # Pierwsze 3 znaki
expr string : ing       # Ostatnie 3 znaki są zgodne ale porównujemy od początku
expr string : strg      # nie może być żadnych różnic
expr string : '.*'      # .* oznacza dowolny ciag znakow - inaczej mowiac otrzymujemy dlugosc ciagu z argumentu 1
expr string : '.*i'     # .*i kazdy ciąg kończący się na i
expr abecadlo : '[abcde]*' # co się stało?

read

Instrukcja read służy do pobierania od użytkownika ciągu znaków i podstawienia go pod wartość zmiennej.

read zmienna2
echo $zmienna2

Przykład

touch a.txt
printf "a\nbb\nccc\n" >> a.txt

Zapisz i wykonaj skrypt

#! /bin/sh
cat a.txt |
while read linia
do

        x=`expr $linia : '.*'`
        if [ "$x" -ge 2 ]
        then
                echo $linia
        fi
done

cat a.txt |
while read linia
do
        if [ `expr $linia : '.*'` -le 2 ]
        then
                echo $linia
        fi
done

Przykłady

Przykład: Czyta wartość i nazwę zmiennej, pzypisuje zmiennej tę wartość, exportuje ją i wypisuje zmienne dostępne w systemie.

#!/bin/sh
echo "Enter variable name and value separated by a space"
read VARIABLE VALUE
echo Assigning the value $VALUE to variable $VARIABLE
eval $VARIABLE=$VALUE

# print the value
eval echo "$"$VARIABLE

# export the value
eval export $VARIABLE

# print the exported variables.
export

Przykład: Symulowanie tablicy za pomocą eval.

#!/bin/sh

COUNTER=0

VALUE="-1"

echo "Enter a series of lines of test.  Enter a blank line to end."

while [ "x$VALUE" != "x" ] ; do

        read VALUE

        eval ARRAY_$COUNTER=$VALUE

        eval export ARRAY_$COUNTER

        COUNTER=$(expr $COUNTER '+' 1) # More on this in Paint by Numbers

done

COUNTER=$(expr $COUNTER '-' 1) # Subtract one for the blank value at the end.

# print the exported variables.

COUNTERB=0;

echo "Printing values."

while [ $COUNTERB -lt $COUNTER ] ; do

        echo "ARRAY[$COUNTERB] = $(eval echo "$"ARRAY_$COUNTERB)"

        COUNTERB=$(expr $COUNTERB '+' 1) # More on this in Paint by Numbers

done

exit

Zadania

  1. Napisz skrypt, który wczytuje nazwę folderu jako 1 argument skryptu i tworzy plik "output.txt", który zawiera nazwy wszystkich pustych podfolderów w tym folderze (mających zero plików w środku).

  2. Napisz skrypt, który jako argument otrzymuje nazwę pliku i usuwa wszystkie powtarzające się linie z tego pliku

  3. Napisz skrypt, który wczytuje dwie daty urodzenia jako argument w postaci MM/DD/YYYY (n.p. 08/31/1956) i określa czy daty te wskazują na ten sam dzień tygodnia.

*

Wykorzystano materiały z:

http://www.cs.put.poznan.pl/csobaniec/edu/sop/doc/sop1.pdf

https://bap.faculty.wmi.amu.edu.pl/index.php/dydaktyka/dsop/

http://www.kalkowski.name/dydaktyka/2012-2013-Z/DSOP/zajecia-skrypty-2/

http://www.softpanorama.org/Utilities/eval.shtml

http://www.softpanorama.org/Utilities/read.shtml