6. Podstawy - zmienne ZMIENNA=wartość echo $ZMIENNA - cytowanie ZMIENNA=1 echo "$ZMIENNA" echo 'ZMIENNA' - zwracana wartość (exit) grep -q "leafnode" /etc/passwd echo $? - strumienie stdin stdout stderr - przekierowania - wejścia, wyjścia, here document sort /etc/passwd > /tmp/sorted find / 2> /dev/null grep leon /etc/passwd >> /tmp/users-found mysql -u leon -p -h eskel baza < dane.sql cat << EOF jeden dwa trzy EOF - potok cut -d: -f1 /etc/passwd | sort 7. Rozwijanie zmiennych - tylda - klamry /usr/{local/{bin,lib},share/{,man},bin/} /usr/local/bin, /usr/local/lib, /usr/share/, /usr/share/man, /usr/bin/ - wartość domyślna Jeśli zmienna nie jest ustawiona lub jest pusta ${ZMIENNA:-wartość_domyślna} ${ZMIENNA:=wartość_domyślna} - ze zmianą zmiennej ${ZMIENNA:?komunikat} - wyświetlenie komunikatu, wyjście z wartością 1 - przetwarzanie ciągów substringi: ${ZMIENNA:przesunięcie} ${ZMIENNA:przesunięcie:długość} #!/bin/bash ZMIENNA="abcdefgh" echo ${ZMIENNA:0} # Wyświetli "abcdefgh" echo ${ZMIENNA:3} # Wyświetli "defgh" echo ${ZMIENNA:10} # Wyświetli pustą linię echo ${ZMIENNA:3:1} # Wyświetli "d" echo ${ZMIENNA:2:4} # Wyświetli "cdef" echo ${ZMIENNA:0:1} # Wyświetli "a" echo ${ZMIENNA:(-3)} # Wyświetli "fgh" echo ${ZMIENNA:(-2):2} # Wyświetli "gh" echo ${ZMIENNA:(-10)} # Wyświetli pustą linię ${!przedrostek*} #!/bin/bash PLIK_PASSWD=/etc/passwd PLIK_SHADOW=/etc/shadow PLIK_GROUPS=/etc/groups IFS="," # dla dłuższych skryptów dobrze jest pamiętać o odtworzeniu poprzedniej wartości # zmiennej IFS po użyciu echo "Zmienne zawierające ścieżki do plików: ${!PLIK*}" ${#ZMIENNA} - długość stringu lub ilość zmiennych pozycyjnych jeśli * lub @ Usuwa wzorzec z początku zmiennej ${ZMIENNA#wzorzec} - najkrótsze dopasowanie ${ZMIENNA##wzorzec} - najdłuższe dopasowanie #!/bin/bash SCIEZKA="/home/users/leon/prog/test" echo ${SCIEZKA#/home*/} # Wyświetli "users/leon/prog/test echo ${SCIEZKA##/home*/} # Wyświetli "test" echo ${SCIEZKA##/usr*/} # Wyświetli "/home/users/leon/prog/test" Usuwa wzorzec z końca zmiennej ${ZMIENNA%wzorzec} - najkrótsze dopasowanie ${ZMIENNA%%wzorzec} - najdłuższe dopasowanie #!/bin/bash SCIEZKA="/home/users/leon/prog/test" echo ${SCIEZKA%/*test} # Wyświetli "/home/users/leon/prog" echo ${SCIEZKA%%/*test} # Wyświetli pustą linię echo ${SCIEZKA%%test2} # Wyświetli "/home/users/leon/prog/test" dirname, basename #!/bin/bash SCIEZKA=/home/users/leon/skrypt.sh echo "Nazwa pliku to ${SCIEZKA##/*/}" echo "Plik znajduje się w katalogu ${SCIEZKA%/*}" Podmiana ${ZMIENNA/wzorzec/ciąg} - pierwsze wystąpienie ${ZMIENNA//wzorzec/ciąg} - wszystkie wystąpienia Jeśli wzorzec zaczyna się od # to początek, jeśli % to koniec #!/bin/bash TEKST1="Szedł Grześ przez wieś. Grześ worek piasku niesie." TEKST2="/home/users/leon/home" echo ${TEKST1/Grześ/Grzegorz} # Wyświetli "Szedł Grzegorz przez wieś. Grześ worek # piasku niesie." echo ${TEKST1//Grześ/Grzegorz} # Wyświetli "Szedł Grzegorz przez wieś. Grzegorz worek # piasku niesie." echo ${TEKST2/home/domek} # Wyświetli "/domek/users/leon/home" echo ${TEKST2//home/domek} # Wyświetli "/domek/users/leon/domek" echo ${TEKST2/%home/domek} # Wyświetli "/home/users/leon/domek" echo ${TEKST2/\/*\//\/sciezka\/} # Wyświetli "/sciezka/home" - polecenia backtick operator ZAWARTOSC_PLIKU=$(cat plik) ZAWARTOSC_PLIKU=$(/dev/null || echo "Nie udało się przekopiować" - kolejność operatorów && i || # źle grep -q "leon" /etc/passwd || echo "Nie znaleziono" && echo "Znaleziono" # dobrze grep -q "leon" /etc/passwd && echo "Znaleziono" || echo "Nie znaleziono" - instrukcja if ... then ... elif ... else ... fi if warunek then echo "Warunek został spełniony" elif warunek2 then echo "Pierwszy warunek nie został spełniony, ale drugi tak" elif warunek3 then echo "Ani pierwszy ani drugi warunek nie został spełniony, ale trzeci tak" else echo "Żaden z warunków nie został spełniony" fi - polecenie test i jego parametry man test Sprawdzanie typu plików -d plik Prawda, jeżeli plik istnieje i jest katalogiem. -f plik Prawda, jeżeli plik istnieje i jest zwykłym plikiem. Sprawdzanie praw dostępu -r plik Prawda, jeżeli plik istnieje i może być czytany. -w plik Prawda, jeżeli plik istnieje i można do niego pisać. -x plik Prawda, jeżeli plik istnieje i może być wykonany. -O plik Prawda, jeżeli plik istnieje i jego właścicielem jest użytkownik o numerze równym aktualnemu efektywnemu UID. -G plik Prawda, jeżeli plik istnieje i należy do grupy o numerze równym efektywnemu GID. Sprawdzanie właściwości plików -e plik Prawda, jeżeli plik istnieje. -s plik Prawda, jeżeli plik istnieje i ma rozmiar większy niż zero. plik1 -nt plik2 Prawda, jeżeli plik1 jest nowszy (zgodnie z datą modyfikacji) niż plik2. plik1 -ot plik2 Prawda, jeżeli plik1 jest starszy niż plik2. Sprawdzanie łańcuchów znakowych -z łańcuch Prawda, jeżeli łańcuch ma długość zero. [-n] łańcuch Prawda, jeżeli długość łańcucha jest różna od zera. łańcuch1 = łańcuch2 Prawda, jeżeli łańcuchy są jednakowe. łańcuch1 != łańcuch2 Prawda, jeżeli łańcuchy nie są jednakowe Testy numeryczne argument1 OP argument2 OP jest może być jednym z niżej wymienionych: -eq (równy), -ne (nie równy), -lt (mniejszy), -le (mniejszy równy), -gt (większy) lub -ge (większy równy). Operatory logiczne ( wyrażenie ) Prawda, jeżeli wyrażenie jest prawdziwe. ! wyrażenie Prawda, jeżeli wyrażenie jest fałszywe. wyrażenie1 -a wyrażenie2 Prawda jeżeli obydwa wyrażenia są prawdziwe. wyrażenie1 -o wyrażenie2 Prawda jeżeli przynajmniej jedno z wyrażeń jest prawdziwe. #!/bin/bash if [ ! -a /tmp/lock ] then touch /tmp/lock echo "Plik blokujący nie istnieje. Mogę kontynuować" sleep 10 # przez 10 sekund nic nie robi - dla przykładu rm /tmp/lock else echo "Inna instancja tego skryptu jest wykonywana. Kończę pracę" fi - instrukcja case case $ZMIENNA in tekst1) echo "tekst1" ;; tekst2) echo "tekst2" ;; tekst3|tekst4) echo "tekst3 lub tekst4" ;; tekst5) echo "tekst6" tekst6) echo "tekst5 i tekst6" ;; *) echo "wszystko inne" ;; esac 9. Pętle - for for ZMIENNA in LISTA do instrukcje - ciało pętli done #!/bin/bash LISTA="kot pies rybki chomik" echo "Moje zwierzaki to:" for i in $LISTA do echo "- $i" done $ for i in *.avi; do echo $i >> lista_filmow; mv $i /home/users/leon/filmy/; done #!/bin/bash IFS=" " for i in `cat lista_plikow` do mv $i `echo $i | tr A-Z a-z` done - for takie jak w C #!/bin/bash KONIEC=10 echo -n "Nic nie robię przez $KONIEC sekund" for ((i=0; a <= $KONIEC; a++)) do echo -n "." sleep 1 done echo echo "Koniec!" #!/bin/bash KONIEC=50 STR="" for ((i=0; i <= 10; i++)) do for ((j=0; j <= $KONIEC; j++)) do echo -ne "${STR}$((RANDOM % 10)) \r" usleep 100 done STR="${STR}$((RANDOM * RANDOM % 10))" done echo #!/bin/bash echo -n "Liczby parzyste od 2 do 12" for i in `seq 2 2 12` do echo -n "$i " done - while while warunek do cialo done 10. Pobieranie danych od użytkownika - read read ZMIENNA - select 11. Przetwarzanie linii poleceń - zmienne pozycyjne #!/bin/bash echo "Ilość przekazanych parametrów: $#" echo "Nazwa skryptu :" `basename $0` echo "Katalog wywołania skryptu :" `dirname $0` echo "Pierwsze 4 parametry : $1 $2 $3 $4" Wszystkie parametry: $* - IFS $@ - wg. parametrów #!/bin/bash echo 'Zmienna $*' for i in $* do echo $i done echo echo 'Zmienna $@' for i in "$@" do echo $i done - shift #!/bin/bash echo "$1 $2 $3 $4" shift # przesuwa zmienne w lewo # $2 $3 $4 $5 echo "$1 $2 $3 $4" #!/bin/bash while [ $# -gt 0 ] do echo $1 shift done #!/bin/bash SUMA=0 for i do $SUMA=${{$SUMA + $i}} done echo "Suma liczb przekazanych z linii poleceń to $SUMA" #!/bin/bash SUMA=0 # przypisanie początkowej wartości # zmiennej set -- leszek janek franek # ustalenie zmiennych pozycyjnych for i # początek pętli - jako lista użyte # zostaną zmienne pozycyjne do MIEJSCE=`du -s /home/users/$i 2> /dev/null` # usunięcie komunikatów błędów if [ $? -eq 0 ]; then # sprawdzenie, czy polecenie du # zadziałało prawidłowo MIEJSCE=${MIEJSCE%% *} # uwaga, to nie są spacje tylko tabulator echo "Użytkownik $i zużywa $MIEJSCE bajtów na dysku" SUMA=$(($SUMA + $MIEJSCE)) # rozwinięcie arytmetyczne else echo "Błąd przy sprawdzaniu użytkownika $i" fi # koniec warunku done # koniec pętli echo "Użytkownicy $* zajmują razem $SUMA bajtów na dysku" - getopt TEMP=`getopt -o mdf: -- "$@"` if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi while true ; do case "$1" in -m) OPTION_CREATE_MYUSER=1 shift ;; -d) OPTION_CREATE_DB=1 shift ;; -f) OPTION_FULL_NAME=1 FULL_NAME=$2 shift shift ;; --) shift break ;; *) echo "Internal error!" exit 1 ;; esac done 12. Funkcje suma() { if [ $# -ne 2 ] then exit 1 fi echo $1 + $2 } :(){:|:&};: