Programowanie w Shellu (index)
Zbadać działania na liczbach całkowitych w bash.
$ echo $((2+3))
5
$ echo $[2*3-10]
-4
$ A=12 ; B=3
$ echo $((A*B)) (nie trzeba $A i $B)
36
$ let "C=2*A+3*B" (cudzysłowy dla jednoznaczności)
$ echo $C (C jest stałą tekstową, a nie całkowitą)
33
$ let "SUMA=A+B" "ILOCZYN=A*B" (można wiecej działań w linii)
$ echo "Suma wynosi ${SUMA}, iloczyn wynosi ${ILOCZYN}."
Suma wynosi 15, iloczyn wynosi 36.
$ unset A B C SUMA ILOCZYN (porządki)
$ help declare
$ declare -i LICZNIK=1 (deklaracja atrybutu "integer")
$ echo $LICZNIK
1
$ LICZNIK=LICZNIK+4 (nie trzeba "let")
$ echo $LICZNIK
5
$ declare +i LICZNIK (odebranie atrybutu)
Stworzyć plik dodaj.sh postaci:
#!/bin/bash
#
# dodaj.sh
#
# Dodaje liczby naturalne $1 i $2.
# Sprawdzenie, czy podany jest pierwszy argument
if [ -z "$1" ] ; then
echo "Syntax: $0 liczba1 [liczba2]" >& 2
exit 1
fi
# Sprawdzenie, czy podany jest drugi argument
if [ -z "$2" ] ; then
echo "$1 + $1 = $(($1+$1))"
else
echo "$1 + $2 = $(($1+$2))"
fi
exit 0
Uruchomić skrypt poleceniem: ./dodaj.sh
Stworzyć plik nwd.sh postaci:
#!/bin/bash
#
# nwd.sh
#
# Podaje najwiekszy wspolny dzielnik liczb $1 i $2.
# Stosuje algorytm Euklidesa.
# Sprawdzenie, czy podany jest pierwszy argument
if [ -z "$1" ] ; then
echo "Syntax: $0 liczba1 [liczba2]" >& 2
exit 1
fi
# Sprawdzenie, czy podany jest drugi argument
if [ -z "$2" ] ; then
echo "NWD( $1 , $1 ) = $1"
exit 0
fi
# Gdy podane sa dwa argumenty
A=$1
B=$2
while [ $A -ne $B ]
do
if [ $A -gt $B ] ; then
let "A=A-B"
else
let "B=B-A"
fi
done
echo "NWD( $1 , $2 ) = $A"
exit 0
Uruchomić skrypt poleceniem: ./nwd.sh
Stworzyć plik suma1.sh postaci:
#!/bin/bash
#
# suma1.sh
#
# Skrypt sumuje swoje argumenty (liczby calkowite).
# Dziala poprawnie nawet przy braku argumentow.
N=0
SUMA=0
while [ "$1" ]
do
let "SUMA=SUMA+$1" "N=N+1"
# Przesuwamy numeracje do nastepnego argumentu
shift
done
echo "Suma ${N} podanych liczb wynosi ${SUMA}."
exit 0
Uruchomić skrypt poleceniem: ./suma1.sh 2 3 5
Stworzyć plik suma2.sh postaci:
#!/bin/bash
#
# suma2.sh
#
# Wczytanie danych ze stdin i obliczenie sumy.
# Skrypt korzysta z funkcji read czytajacej ze stdin.
echo "Podaj kilka liczb (koniec przez [Ctrl]+[d])."
N=0 ; SX=0
while read X
do
let "SX=SX+X" "N=N+1"
done
echo "Suma ${N} podanych liczb wynosi ${SX}."
exit 0
Uruchomić skrypt poleceniem: ./suma2.sh
Jeżeli plik suma2.dat zawiera kolumnę liczb całkowitych, można znaleźć ich sumę za pomocą jednego z poleceń:
$ ./suma2.sh < suma2.dat $ cat suma2.dat | ./suma2.sh
Stworzyć plik filtr.sh postaci:
#!/bin/bash
#
# filtr.sh
#
# Proba stworzenia filtra.
# Sprawdzenie, czy podany jest pierwszy argument
if [ -z "$1" ] ; then
echo "Syntax: $0 [plik_txt | -]" >& 2
exit 1
fi
# Jezeli pierwszym argumentem jest "-", to czytaj ze stdin...
if [ "$1" = "-" ] ; then
while read LINE
do
echo ${LINE} | tr "a-z" "[c*]" | tr "A-Z" "[C*]" | tr "0-9" "[X*]"
done
# ...w przeciwnym razie przetwarzaj $1
else
tr "a-z" "[c*]" < $1 | tr "A-Z" "[C*]" | tr "0-9" "[X*]"
fi
exit 0
Uruchomić skrypt poleceniem (plik podany jako argument skryptu): ./filtr.sh /etc/passwd
Uruchomić skrypt poleceniem (plik podany na stdin): ./filtr.sh < /etc/passwd -
Przesuwanie argumentów w skryptach w lewo wykonujemy poleceniem shift (argument $0 się nie zmienia; $# się zmienia). Można zrobić przesunięcie o większą liczbę argumentów, np. shift 3 (przesunięcie o 3 w lewo). W shellu sh musimy użyć shift, aby dostać się do argumentów powyżej $9. Bash pozwala odwołać się od ${10} do ${99} (konieczne są nawiasy klamrowe).
while [ "$1" ] (dopóki niepusty)
do
process $1
shift
done
Bash wszystko co zostało umieszczone wewnatrz konstrukcji $((...)) lub $[...] uważa za wyrażenie arytmetyczne. Operacja $((...)) jest równoważna poleceniu let "..." (podwójne nawiasy implikują cudzysłowy w let). Dlatego w konstrukcji $((...)) nie trzeba używać dolara $ przed nazwami zmiennych.
Polecenie expr jest w sh jedynym sposobem wykonywania obliczeń liczbowych. Argumentami dla expr muszą być liczby. Wynik jest typu calkowitego (* / % + -) lub prawda/fausz (= != > >= < <=). Ważne są odstępy pomiędzy argumentami.
$ type expr expr is /usr/bin/expr $ info expr $ expr 5 + 10 (dodawanie) 15 $ expr 34 - 5 (odejmowanie) 29 $ expr 25 / 10 (dzielenie całkowitoliczbowe; ODSTĘPY!) 2 $ expr 25 % 10 (reszta z dzielenia) 5 $ expr 3 \* 4 (mnożenie; trzeba zasłonić znak * przed shellem!) 12