Systemy operacyjne

Opis zajęć i zasad

Zajęcia 4

Metasymbole powłoki *

/

/ - znak oddzielający kolejne elementy ścieżki do pliku

cd /tmp
cd /home/staff/kalkos

;

; - znak oddzielający polecenia wykonywane jedno po drugim

echo hello; sleep 3; ls

&

& - znak dodany na końcu polecenia powoduje, że polecenie wykonuje się w tle

sleep 100 &
jobs
fg %1
sleep 100
# wcisnij ctr + C

&&

&& - instrukcja łączaca dwa polecenia logicznym "i", która zadziała w taki sposób że polecenie podane jako drugie w kolejności wykona się pod warunkiem że pierwsze zakończy działanie poprawnie. W przeciwnym przypadku drugie polecenie nie wykona się.

sleep 3 && echo hello $ odczekaj 3 sekundy
sleep 3 && echo hello
# wcisnij ctr + C

W pierwszym wykonaniu polecenie sleep 3 zakończyło pomyślnie swoje działanie, a w drugim polecenie sleep 3 nie zakończyło się pomyślnie - zostało przerwane (Ctrl-C).

()

() - polecenia znajdujące się w takich nawiasach są wykonywane w uruchomionej w tym celu powłoce bash, a standardowe wyjście tych poleceń jest przekazywane jako jeden strumień w bieżącej powłoce.

pwd
/home/centuria/kalkos/test
find ./
mkdir test
echo "hello" > ./test/plik.txt
(cd ./test/; cat ./plik.txt)
(pwd; cd test; pwd) ; (mkdir test2; echo "hi" > ./test2/plik2.txt)

{}

{} - rozwinięcie, podmiana wartości, tzw. brace expansion

echo po{drecznik,koj,rozmawiac}
echo {1,2,3}a{4,5,6}
echo {a..z}
echo {A..Z}{000..100}
echo {00..100}
echo {0..100}
echo {AA..ZZ}
echo To jest wyr{az,ocznia,ko}
echo "To jest wyr{az,ocznia,ko}"
echo "To jest wyr"{az,ocznia,ko}
touch a.txt; touch b.txt; touch c.txt
echo a > a.txt; echo b > b.txt; echo c > c.txt
cat {a.txt,b.txt,c.txt} > d.txt # łączy pliki a, b, and c w plik d
cat d.txt
cp d.{txt,backup} # Kopiuje "d.txt" do "d.backup"

Różnica między () a []

(cd /usr; pwd); pwd
{ cd /usr; pwd; }; pwd

|

| - przekierowaie wyjścia jednego polecenia na wejście innego - omówione na poprzednich zajęciach.

[]

[]- testuje wartość wyrażenia (zostanie omówione przy skryptach)

||

|| - instrukcja łączaca dwa polecenia logicznym "or", która zadziała w taki sposób że polecenie podane jako drugie w kolejności wykona się pod warunkiem że pierwsze zakończy działanie niepoprawnie. W przeciwnym przypadku drugie polecenie wykona się.

sleep 3 || echo hello
sleep 3 || echo hello
# wciśnij CTR + C

W pierwszym wykonaniu polecenie sleep 3 zakończyło pomyślnie swoje działanie, a w drugim polecenie sleep 3 nie zakończyło się pomyślnie - zostało przerwane (Ctrl-C).

<<

<< przekazanie wejścia polecenia do czasu odczytania linii zawierającej zadany ciąg znaków.

cat << c
a
b
c

\

Znak \ służy do poprzedzania znaku specjalnego

echo Znak \$ służy do poprzedzania wartosci zmiennej

.

Związuje źródło powłoki z plikiem (równoważne komendzie source)

echo ls > plik.sh
. plik.sh
printf '#!/bin/bash' > a.sh
printf "\n" >> a.sh
echo "exit" >> a.sh
chmod +x a.sh
./a.sh #uruchamia skrypt jako program
. ./a.sh # zmienia związuje źródło z powłoką UWAGA wywołanie spowoduje wylogowanie z powłoki!

#

# - komentarz

echo hello # world i inny komentarz

' oraz "

Służą do podawania stringów, ' jest mocniejsze i zachowuje wszystkie znaki specjalne we wpisanej formie, " przetwarza symbole na znaki specjalne.

Więcej na ten temat można znaleźć tutaj http://tldp.org/LDP/abs/html/escapingsection.html

Zmienne

Zmienne powłoki pozwalają przypisać nazwie symbolicznej pewien ciąg znaków lub liczbę całkowitą. Zmienną taką definiujemy przez instrukcje przypisania o postaci

zmienna=wartość

gdzie:

zmienna jest nazwa zmiennej,

wartość jest ciągiem znaków, który przypisujemy danej zmiennej.

Istotny jest tu brak odstępów przed i po znaku równości. Gdyby go wstawić, nazwa zmiennej byłaby traktowana jako polecenie.

a=1
a= 1
a =1
b=Ala
b=Ala ma kota
b="Ala ma kota"
b='Ala ma kota'

Które operacje zakończyły się błędem?

Od chwili zdefiniowania zmiennej możemy używać jej nazwy wszędzie tam, gdzie chcielibyśmy napisać ciąg znaków wartość. Nazwę zmiennej musimy poprzedzić znakiem $, tj. musimy napisać

$zmienna

lub

${zmienna}

Tej drugiej postaci używamy zazwyczaj wtedy, gdy powłoka może mieć problem z jednoznacznym określeniem nazwy zmiennej.

Przykłady:

system=UNIX
echo To jest system $system   #  Zostanie wypisany tekst: To jest system UNIX
txt=abc
echo ${txt}def #  Zostanie wypisany tekst abcdef. Jeśli nazwa zmiennej txt nie byłaby zamknięta w nawiasy, to powłoka szukałaby zmiennej txtdef

Usuwanie zmiennych:

x=5
echo x
echo $x
unset x
echo $x

Zauważ, że niezdefiniowana zmienna jest traktowana jako pusty ciąg znaków.

Dostępność zmiennych w potomnych procesach:

x=10
echo $x
sh #uruchamiamy proces potomny, powłokę kolejną
echo $x
exit #wychodzimy z podprocesu

Wywoływanie zmiennych:

x=ls
$x # powłoka interpretuje to jak wpisanie ls
x="ls -l"
$x

Zmienne systemowe

Powłoka Bash pozwala na definiowanie stałych i zmiennych lokalnych i globalnych (zwanych środowiskowymi). Zmienne te wpływają na funkcjonowanie powłoki i wykonywanych w niej poleceń. W powłoce, uruchamianej po zalogowaniu się użytkownika, jest zdefiniowanych wiele zmiennych (ich liczba i nazwy zależą od rodzaju powłoki). Poniżej zamieszczono przykłady ważniejszych zmiennych predefiniowanych przez system operacyjny lub powłokę:

$ - Wyświetla parametry pozycyjne

$ - Numer procesu powłoki

PPID - Numer procesu rodzicielskiego

HOME - Prywatny katalog użytkownika

PWD - Katalog aktualny

OLDPWD - Katalog sprzed ostatniej komendy cd

SHELL - Nazwa powłoki

RANDOM - Liczba losowa

PATH - Scieżka przeszukiwań

SECONDS - Liczba sekund od rozpoczęcia pracy

PS1 - Tekst wyświetlany jako znak zachęty

PS2 - określa ciąg znaków zachęty dodatkowy - w przypadku gdy bash potrzebuje dodatkowych danych z wejścia

TERM - Nazwa terminala, z którego pracuje użytkownik

Wyświetlanie wartości zmiennych:

echo $$
echo $HOME
cd /
cd $HOME
echo $PPID #itd. dla każdej zmiennej

Znak zachęty

Znak zachęty to tekst, który informuje użytkownika, że system czeka na wprowadzenie przez niego danych. W powłoce bash istnieją dwa poziomy znaku zachęty - pierwszy, który otrzymamy zaraz po zalogowaniu informuje nas, że system czeka na wprowadzenie polecenia. Drugi poziom jest wyświetlany gdy interpreter potrzebuje dodatkowych danych, które musimy wprowadzić. Jest on przechowywany w zmiennej PS2 i standardowo ma postać ">". Jeśli wydamy polecenie:

PS1="To mój komputer"
PS1="[\t] \$"

wtedy nasz znak zachęty będzie wyglądał: To mój komputer.

Standardową zmienną PS1 ma postać:

export PS1="[\u@\h \W]\\$ "

Pierwszy znak [- jest znakiem statycznym, dzięki niemu dane przedstawione są w estetycznej formie, kod u wyświetla identyfikator użytkownika, @ to następny znak statyczny, h pokazuje nazwę komputera, a W wyświetla podstawową nazwę katalogu. Następnie znak ] zamyka nawias, a po nim następuje kod $, który wyświetla znak # gdy jesteśmy zalogowani jako root, lub $ gdy jako zwykły user. Spacje są znakami wyświetlanymi na ekranie.

Lista kodów specjalnych, które mogą zostać użyte do konfiguracji znaku zachęty:

\d - wyświetla datę

\t - wyświetla czas

\h - wyświetla nazwę komputera

PATH

PATH – zmienna środowiskowa używana w systemach operacyjnych do określania zestawu katalogów, gdzie zlokalizowane są programy komputerowe w celu ich uruchomienia.

echo $PATH

W momencie wydania przez użytkownika dowolnego polecenia, system przeszukuje ścieżki po każdym elemencie po kolei (w kierunku od lewej do prawej), szukając nazwy pliku, który pasuje do nazwy wydanego polecenia. Jeżeli taki program zostanie odnaleziony, zostanie on wykonany jako proces potomny powłoki systemowej lub programu, który go wywołał. Jeżeli program nie zostanie odnaleziony, użytkownik otrzyma odpowiedni komunikat o nieodnalezieniu żądanego programu.

Przykład:

PATH=/tmp
ls
PATH=/bin:/usr/bin

Skrypty

Skryptem nazywamy plik tekstowy, ktory możemy przekazać jako parametr dla powłowi bash lub też możemy mu nadać uprawnienia i zostanie wykonany. Służy do tego symbol ./ .

Przykład:

echo "echo moj pierwszy skrypt"> a.sh
./a.sh
/bin/bash a.sh # przekazujemy do powłoki bash do wywołania skrypt
sh a.sh # analogicznie jak wyżej
chmod +x a.sh
./a.sh

Przykład:

echo '#!/bin/bash' > a.sh
echo "echo moj drugi skrypt" >> a.sh
cat ./a.sh
./a.sh

Pierwsza linia skryptu nazywana shebang zaczynająca się od znaków: #! choć wygląda jak komentarz, nie jest nim - ma szczególne znaczenie - wskazuje na interpreter który powinien zostać użyty do wykonania skryptu, ścieżka do niego musi być podana w postaci bezwzględnej (nie można użyć dajmy na to samego bash) i musi się znajdować w pierwszej linii skryptu, bez żadnych poprzedzających odstępów. Tutaj skrypt zawsze będzie wykonywany przez interpreter poleceń /bin/bash, niezależnie od tego jakiego rodzaju powłoki w danej chwili używamy.

Jeżeli nie podamy shebang w pierwszej linii system będzie starał się wykonać program jako skrypt powłoki.

Parametry i zmienne

Skrypt może zostać uruchomiony z argumentami, np.:

./a.sh a b c d

Argumenty są dostępne przez parametry pozycyjne (positional parameters):

echo "echo \$0" > a.sh
echo "echo \$1" >> a.sh
echo "echo \$2" >> a.sh
./a.sh ala ma kota
echo "echo \$3" >> a.sh
./a.sh ala ma kota
./a.sh a b c
./a.sh "a b" c
./a.sh a\ b c
./a.sh *
./a.sh "*"
./a.sh \*

Polecenie shift n przesuwa zawartość zmiennych o n w lewo (domyślnie \(n = 1\)).

Przykłady:

echo "shift 1" > a.sh
echo "echo \$1" >> a.sh
echo "echo \$2" >> a.sh
echo "echo \$3" >> a.sh
./a.sh ala ma kota

Zmienne specjalne

$0 – ścieżka do skryptu (nazwa wykonywanego skryptu)

$# – liczba argumentów

$* – wszystkie parametry pozycyjne jako jeden napis ("$1 $2 ..."

$@ – wszystkie parametry pozycyjne jako osobne napisy ("$1" "$2" ...)

$$ – PID procesu skryptu

echo "echo \$1" > a.sh
echo "echo \$2" >> a.sh
echo "echo \$3" >> a.sh
echo "echo \$*" >> a.sh
echo "echo \$#" >> a.sh
./a.sh ala ma kota

Polecenia

env

Samo polecenie env wyświetla parametry otoczenia

env

env służy do uruchamiania polecenia w powloce, która ma zmodyfikowane parametry (ustawione zmienne). Przykład:

echo "echo \$zmienna" > a.sh # wpisujemy to do pliku
cat a.sh
chmod +x ./a.sh # dodajemy prawa do wykonania
env zmienna=9 ./a.sh # uruchamiamy ustawiając wartość zmiennej na 9

echo

echo wyświetla wartość zmiennych na ekranie

echo "Ala ma psy"
echo Ala ma psy
zmienna=2
echo Ala ma $zmienna psy
echo "Ala ma $zmienna psy"
echo "Ala ma ".$zmienna." psy"
echo 'Ala ma $zmienna psy'

eval

eval wywołuje komendę jak skrypt shellowy

Wywoływanie zmiennych:

x="sleep 2; ls"
$x
eval $x

Przykład 1:

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

Przykład 2:

zmienna=1
zmienna1=2
eval echo \$zmienna$zmienna
a=1 b=5
echo {$a..$b}
eval echo {$a..$b}

export

Instrukcja "export" służy do ustawiania zmiennych by były przekazywane do podpowłoki. Bez podania parametru export wyświetla zawartość zmiennych, które podlegają eksportowi.

export

Przykład

export zmienna=1
export
echo $zmienna

Dostępność zmiennych w potomnych procesach:

x=10
echo $x
export x
sh
echo $x
export
exit
export