Instytut Systemów Elektronicznych
Politechnika Warszawska
Materiały pomocnicze do przedmiotu
Podstawy Techniki Komputerowej
Powłoka systemu UNIX
Do użytku wewnętrznego
Opracował: dr inż. Edward Śliwa
Warszawa, kwiecień 1995 r.
Powłoka (ang. shell) jest interfejsem między użytkownikiem
a systemem operacyjnym. Jej podstawową funkcją jest interpretacja i wykonanie
poleceń użytkownika. W celu ułatwienia wprowadzania często powtarzających
się ciągów poleceń dla systemu operacyjnego powłoka udostępnia język
programowania poleceń użytkownika (będzie on dalej nazywany językiem
powłoki).
Najczęściej stosowanymi powłokami w różnych implementacjach systemu
UNIX są:
-
powłoka Bourne'a (sh)
-
powłoka Korna (ksh)
-
powłoka C (csh)
lub ich modyfikacje, będące dziełem różnych programistów i udostępnione
przez nich do swobodnego wykorzystania (np. powłoki: bash, zsh,
tcsh).
Niniejsze opracowanie zawiera opis podstawowych własności powłoki ksh.
Praktycznie wszystkie podane tu informacje odnoszą się również do powłok
zsh i POSIX-sh, większość także do powłoki sh.
1. Podstawowe pojęcia
Użytkownik może wprowadzać polecenia dla systemu operacyjnego na dwa sposoby:
-
wypisując je z klawiatury, lub
-
umieszczając ciąg poleceń w pliku tekstowym, a następnie używając nazwy
tego pliku jako komendy. Plik taki będziemy dalej nazywać skryptem.
Ciąg znaków wprowadzany przez użytkownika z klawiatury (lub linie skryptu)
jest przez powłokę dzielony na słowa, tj. ciągi znaków rozdzielone
którymś z następujących symboli:
; & ( ) | < > nl (nowa linia) spacja
(odstęp) TAB
(powyższe symbole nazywa się metaznakami).
Pierwsze słowo w linii jest nazwą komendy, pozostałe słowa to
parametry przekazywane komendzie, wśród których możemy wyróżnić
opcje, zazwyczaj poprzedzane znakiem - (minus) oraz argumenty.
Niektóre komendy są wbudowane w powłokę (np. komenda cd), zazwyczaj
jednak są to nazwy plików binarnych lub skryptów.
Przykład:
ls -a -l *.c *.h
nazwa opcje argumenty
Linie rozpoczynające się znakiem # są liniami komentarza i są
ignorowane przez powłokę.
Komenda pobiera dane ze standardowego wejścia (ang. standard
input, w skrócie stdin), którym zazwyczaj jest klawiatura terminala.
Wyniki działania komendy są wyprowadzane na standardowe wyjście
(standard output, stdout), którym normalnie jest monitor
terminala. Informacje o błędach są kierowane na standardowe wyjście
diagnostyczne (standard error, stderr). W dalszej części
niniejszych materiałów zostaną opisane sposoby zmiany przywiązania standardowego
wejścia i wyjścia.
Kilka komend można połączyć w potok, rozdzielając je metaznakiem
|, np.:
ls -l | grep kowalski | more
Konstrukcja taka oznacza, że standardowe wyjście pierwszej komendy będzie
standardowym wejściem drugiej komendy potoku, z kolei standardowe wyjście
drugiej komendy będzie standardowym wejściem trzeciej komendy itd. W powyższym
przykładzie wynik działania komendy ls będzie wejściem dla komendy
grep która wybierze linie zawierające słowo kowalski,
a zatem pliki, których właścicielem jest użytkownik kowalski (chyba,
że w nazwie pliku także pojawi się ciąg znaków kowalski). Z kolei
informacja będąca wynikiem działania komendy grep zostanie wyświetlona
na ekranie monitora za pomocą programu more.
Ciąg potoków lub komend oddzielonych znakami ; (średnik) lub
& (ampersand) będziemy nazywać listą komend (lub po
prostu listą). Użycie jako separatora znaku średnika oznacza, że
komenda występująca przed średnikiem musi się zakończyć zanim powłoka rozpocznie
wykonywanie komendy po średniku. Użycie jako separatora znaku &
spowoduje, że komendy rozdzielone tym znakiem będą się wykonywały równolegle
(asynchronicznie).
Przykład:
# Zamiana nazw plików a i b:
cp a tmp ; mv b a ; mv tmp
# Uruchamia kompilację programu bigprog.c i
# jednocześnie pozwala na edycję pliku sub.c.
cc bigprog.c & vi sub.c Każda komenda zwraca pewna wartość całkowitoliczbową,
którą nazywamy statusem wyjścia komendy. Wartość zero oznacza, że
komenda zakończyła się sukcesem. Wartość rożna od zera jest zwracana w
przypadku błędów i sytuacji nietypowych.
2. Zmienne powłoki
Zmienne powłoki pozwalają przypisać nazwie symbolicznej pewien ciąg
znaków lub liczbę całkowitą. Zmienną taką definiujemy przez instrukcje
przypisania o postaci
gdzie:
zmienna jest nazwa zmiennej,
wartość jest ciągiem znaków, który przypisujemy danej zmiennej.
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ć
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
x=5 prog # Definicja zmiennej użyta przed nazwa komendy oznacza,
że zmienna jest znana tylko podczas wykonywania tej komendy.
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ę:
#
Liczba parametrów pozycyjnych (patrz niżej)
$
Numer procesu powłoki
PPID
Numer procesu rodzicielskiego
HOME
Prywatny katalog użytkownika
MAIL
Skrzynka pocztowa 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 znaki gotowości do pracy systemu
PS2
Jak wyżej, w przypadku kontynuacji komendy
EDITOR
Edytor użytkownika
TERM
Nazwa terminala, z którego pracuje użytkownik
Niektóre z powyższych zmiennych (np. PWD, RANDOM)
nie występują w powłoce Bourne'a.
Jak już wspomniano, zestaw komend można zapisać na dysku w postaci skryptu
i wykonać go wypisując jego nazwę. Skrypt taki wykonuje się w osobnej kopii
powłoki. Jeśli wywołamy skrypt podając w oprócz nazwy również parametry,
to parametry te są dostępne wewnątrz skryptu jako zmienne o nazwach $1,
$2, $3, ...$n. Zmienne te noszą nazwę
zmiennych pozycyjnych. Liczba n zmiennych pozycyjnych jest
dostępna jako zmienna $#.
Zmienne powłoki mogą być lokalne, czyli obowiązujące tylko
w danej powłoce, lub środowiskowe (eksportowane). W tym drugim przypadku
obowiązują również w powłokach potomnych, tj. uruchomionych z danej
powłoki (np. przez wykonanie skryptu lub jawne wywołanie programu powłoki).
Zmienna zdefiniowana instrukcją przypisania jest zmienną lokalną. Zmienna
staje się globalna po użyciu nazwy zmiennej jako argumentu komendy
Przykład:
aa=XXX
bb=YYY
export aa
ksh
echo $aa $bb # Zostanie wypisany tekst: XXX (zmienna bb
nie zostala wyeksportowana i nie jest
dostępna w powłoce potomnej)
Listę zdefiniowanych zmiennych powłoki (i przypisane im wartości) można
uzyskać za pomocą komendy set. Listę zmiennych środowiskowych
otrzymamy po użyciu komendy env.
3. Substytucje wykonywane przez powłokę
Polecenia wypisywane przez użytkownika z klawiatury lub programy (skrypty)
w języku powłoki przed próbą wykonania mogą być przez powłokę modyfikowane.
Jedna z takich modyfikacji została już opisana powyżej: ciągi znaków poprzedzone
znakiem $ są interpretowane jako zmienne powłoki i zastępowane
wartościami odpowiednich zmiennych. Modyfikacje wykonywane przez powłokę
będziemy nazywać substytucjami. Użytkownik wykonywanie niektórych
substytucji może zablokować (np. stosując przełączniki powłoki).
3.1. Aliasy
Powłoka sprawdza, czy pierwsze słowo komendy ma zdefiniowany alias
(synonim). Alias, podobnie jak zmienna powłoki, to pewna nazwa, której
przypisano ciąg znaków. Użytkownik może zdefiniować synonimy wybranych
komend za pomocą komendy o postaci
alias synonim=ciąg_znaków
Oczywiście, ciąg_znaków musi być możliwy do zinterpretowania jako
nazwa komendy lub listy komend. Mechanizm aliasów występuje w powłokach
Korna i zsh, nie występuje w powłoce Bourne'a.
Przykłady:
alias dir=ls # Dwa ulubione aliasy użytkowników
alias md=mkdir # systemu MS DOS
alias ll='ls -al'
alias llm='ll | more'
W dwóch ostatnich przykładach znaki cudzysłowu pozwalają przypisać nazwom
ll i llm ciągi znaków zawierające spacje. Z ostatniego
przykładu widać, że przy definicji aliasu można użyć innego aliasu.
3.2. Substytucja ścieżki
Jeżeli pierwszym znakiem słowa jest znak ~ (tylda), to powłoka
zastąpi ten znak nazwą prywatnego katalogu użytkownika. Substytucja taka
będzie wykonana tylko wtedy, jeżeli tylda jest jedynym znakiem w słowie
lub pozostała część słowa rozpoczyna się ukośnikiem. Powłoka interpretuje
również następujące konstrukcje rozpoczynające się od tyldy:
~user
nazwa prywatnego katalogu użytkownika user
~+
nazwa aktualnego katalogu
~-
nazwa katalogu aktualnego przed ostatnią komendą cd
Przykłady:
Jeżeli prywatnym katalogiem użytkownika jest /home/janek, to:
~ = /home/janek
~/doc = /home/janek/doc
~marek/bin = /home/marek/bin
~+/doc = $PWD/doc
3.3. Substytucja wyniku komendy
Użycie konstrukcji o postaci
(gdzie lista oznacza komendę lub ciąg komend/potoków) spowoduje,
że powłoka wykona komendy składające się na listę, i tekst stanowiący
wynik działania ostatniej komendy (tj. wysyłany przez tę komendę na standardowe
wyjście) zastąpi pokazaną wyżej konstrukcję (od znaku $ do nawiasu
zamykającego włącznie). Równoważną konstrukcją do omawianej jest:
(należy zwrócić uwagę, że występujące w tej konstrukcji znaki to "odwrócone"
znaki cudzysłowu).
Przykłady:
Wyświetlenie listy plików, których właścicielem jest użytkownik:
ls -l | grep `who am i`
Przeniesienie plików, których nazwy są wymienione w pliku filelist
do katalogu dane:
mv $(cat filelist) dane/
3.4. Generacja nazw plików
Jeżeli słowo stanowiące część komendy interpretowanej przez powłokę zawiera
znaki
to słowo to zostanie potraktowane jako wzorzec i zastąpione przez powłokę
listą słów - nazw plików lub katalogów pasujących do tego wzorca. Przy
generacji nazw plików obowiązują następujące reguły:
-
znak * oznacza dowolny ciąg znaków (również ciąg pusty),
-
znak ? oznacza jeden dowolny znak,
-
konstrukcja [abc] oznacza dokładnie jeden znak spośród umieszczonych
w nawiasach; użycie znaku ^ jako pierwszego zmienia znaczenie
konstrukcji na: znak inny niż wymienione w nawiasach. Można także w nawiasach
podać zakres znaków przez podanie pierwszego i ostatniego znaku zakresu
rozdzielonych znakiem -.
Przykłady:
a*z
pasuje do nazw plików zaczynających się na literę a i kończących
na literę z, np. az, aaz, axyz.
*.c
pasuje do nazw plików mających końcówkę .c, np. prog.c,
func.c.
[aeou]la
pasuje do nazw: ala, ela, ola, ula.
[A-Za-z]*
pasuje do nazw plików zaczynających się od litery.
4. Cytowanie (quoting)
Może się zdarzyć, że w pewnych sytuacjach powłoka zinterpretuje wprowadzane
komendy niezgodnie z intencją użytkownika. Można się przed tym zabezpieczyć
odbierając niektórym znakom (traktowanym przez powłokę w sposób szczególny)
ich specjalne znaczenie. Służy do tego mechanizm cytowania znaków.
W omawianych w niniejszym opracowaniu powłokach można stosować trzy sposoby
cytowania:
\x
odwrócony ukośnik kasuje specjalne znaczenie znaku stojącego bezpośrednio
za nim,
'...'
pojedyncze znaki cudzysłowu kasują specjalne znaczenie wszystkich znaków
pomiędzy nimi,
"..."
podwójne znaki cudzysłowu kasują specjalne znaczenie wszystkich znaków
pomiędzy nimi, za wyjątkiem znaku $ (substytucja zmiennych powłoki) i znaku
\.
Przykłady:
$ echo \$HOME = $HOME
$HOME = /users/janek
$ X=2 ; echo '$X > 1'
$X > 1
$ echo "$X > 1\n -------"
2 > 1
-------
5. Wyrażenia arytmetyczne
Zmienne powłoki mogą przyjmować wartości całkowitoliczbowe, i na zmiennych
o takich wartościach można wykonywać operacje arytmetyczne. Składnia wyrażeń
arytmetycznych przypomina składnię języka C. Można stosować dwie równoważne
postacie zapisu wyrażeń arytmetycznych:
lub
(w przypadku stosowania drugiej podanej postaci należy pamiętać o odstępach
wokół podwójnych nawiasów).
Przykłady:
x=1; y=2 # przypisanie wartości liczbowych zmiennym x i y
let "x=x+1" # zwiększane wartości x o 1
echo x = $x # zostanie wypisane: x = 2
(( x = x+y )) # tutaj nie jest potrzebne cytowanie
echo x = $x # zostanie wypisane: x = 4
6. Konstrukcje sterujące języka powłoki
Powłoki omawiane w niniejszym opracowaniu udostępniają użytkownikowi wiele
konstrukcji sterujących, pozwalających na warunkowe wykonywanie poleceń,
zautomatyzowanie wykonanie powtarzających się komend itp. Konstrukcje sterujące
powodują, że język powłoki jest w pełni funkcjonalnym językiem programowania.
6.1. Instrukcja warunkowa
Instrukcja warunkowa pozwala wykonać zestaw (listę) komend, jeśli spełniony
jest warunek określony przez użytkownika. Najprostszą postacią instrukcji
warunkowej jest:
Występujący w instrukcji warunek, od którego uzależnione jest wykonanie
zestawu komend lista, to zazwyczaj wyrażenie o następującej postaci:
[[ wyrażenie_warunkowe ]]
gdzie wyrażenie_warunkowe może być jedna z niżej podanych konstrukcji:
-a fname
plik lub katalog o nazwie fname istnieje
-d fname
fname jest nazwa katalogu
-f fname
fname jest nazwa zwykłego pliku
-w fname
użytkownik ma prawo zapisu pliku fname
-x fname
użytkownik ma prawo wykonania pliku fname
napis = wzorzec
napis i wzorzec są zgodne
wyr1 -eq wyr2
wartości wyrażeń wyr1 i wyr2 są równe; zamiast -eq
można użyć: -ne (różne), -lt (mniejsze), - gt
(większe), -le (mniejsze lub równe), - ge (większe lub
równe)
war1 || war2
alternatywa warunków war1 i war2
war1 && war2
koniunkcja warunków war1 i war2
!war
negacja warunku war
Możliwych wyrażeń warunkowych jest zwykle więcej (zależy to od rodzaju
powłoki, najbogatsze możliwości ma powłoka zsh), powyżej wymieniono
te, które są najczęściej używane.
Innym sposobem określenia warunku jest komenda
lub (równoważnie)
Komenda test zwraca wartość zero jeśli warunek jest spełniony,
i wartość rożną od zera w przeciwnym przypadku. Jako warunku można także
użyć dowolnej komendy lub listy komend - warunek będzie spełniony jeśli
komenda taka zakończy się sukcesem, tj. zwróci status wyjścia równy zeru;
w przeciwnym przypadku warunek nie będzie spełniony.
Przykłady.
if [[ "$1" = '-h' ]]
then
echo Sposób użycia:
echo prog [-h] plik1 plik2 ...
fi
if test -f /tmp/xxx
then
rm /tmp/xxx
fi
Oprócz opisanej powyżej, można użyć bardziej rozbudowanych postaci instrukcji
warunkowej:
if warunek
then
lista1
else
lista2
fi
if warunek1
then lista1
elif warunek2
then lista2
elif warunek3
then lista3
...
else lista
fi
W pierwszej z powyższych postaci lista1 zostanie wykonana jeśli
warunek jest spełniony, a lista2 - jeśli nie jest. W drugim
przypadku jeśli spełniony jest warunek1, to zostanie wykonana lista1.
Jeśli nie będzie on spełniony, to zostanie sprawdzony warunek2,
i jeśli będzie on spełniony, to wykonana zostanie lista2 itd. Jeśli
żaden z warunków: warunek1, warunek2, warunek3 ...
nie jest spełniony, to zostanie wykonana lista występująca po klauzuli
else.
Przykład:
if [[ -d $1 ]]
echo Usuwam wszystkie pliki z katalogu $1
rm $1/*
elif [[ -f $1 ]]
echo Usuwam plik $1
rm $1
else
echo Nie znaleziono pliku ani katalogu o nazwie $1
fi
6.2. Instrukcja wyboru
Instrukcja wyboru pozwala wybrać jeden z kilku wariantów (zależnie od wartości
argumentu). Ogólna postać instrukcji jest następująca:
case słowo in
wzorzec1 ) lista1 ;;
wzorzec2 ) lista2 ;;
...
esac
Jeżeli słowo i wzorzec1 są zgodne, to zostaną wykonane komendy
lista1. Jeśli nie, to sprawdzana jest zgodność wyrażeń słowo
i wzorzec2, i w przypadku, jeśli ta zgodność zachodzi, wykonywana
jest lista2, itd. Należy zwrócić uwagę, że kolejne listy są kończone
podwójnym średnikiem (każda lista może składać się z kilku komend oddzielonych
pojedynczymi średnikami).
Przykład:
case $2 in
y* ) echo Yes ;;
n* ) echo No ;;
* ) echo Maybe ;;
esac
W powyższym przykładzie jeśli drugi parametr pozycyjny zaczyna się na literę
y, to zostanie wypisane słowo Yes; jeśli zaczyna się
on na literę n, zostanie wypisane słowo No. Jeśli parametr
ten zaczyna się innym niż y lub n znakiem, zostanie wypisane
słowo Maybe.
6.3. Pętle
Pętla służy do wielokrotnego wykonania ciągu instrukcji. W omawianych
w niniejszym opracowaniu powłokach występują trzy podstawowe rodzaje pętli:
for, while i until. Pętla for pozwala
wykonać ciąg instrukcji sciśle określoną liczbę razy. Ogólna postać instrukcji
jest następująca:
for zmienna in słowo1 słowo2 ...
do
done
Zmiennej zmienna przypisywana jest wartość słowo1, i dla
tak zdefiniowanej zmiennej wykonywane są komendy lista. Następnie
zmienna przyjmuje wartość słowo2, wykonywana jest lista,
itd.
Przykład:
Aby przenieść wszystkie pliki o nazwach zaczynających się na literę
a do katalogu Afiles należy użyć konstrukcji:
for i in a*
do
mv $i Afiles/
done
Pozostałe dwa rodzaje pętli pozwalają na wykonanie ciągu poleceń lista
w zależności od tego, czy warunek (którym może być wyrażenie warunkowe,
komenda lub nawet lista komend) jest spełniony. Ogólna postać obu konstrukcji
jest pokazana poniżej. W instrukcji while warunek sprawdza się
na początku, i lista jest wykonywana tak długo, jak długo warunek
jest spełniony. Oczywiście lista powinna zawierać instrukcje wpływające
na warunek, gdyż w przeciwnym przypadku instrukcja while
albo nie wykonałaby się ani razu, albo wykonywałaby się w nieskończoność.
W pętli until warunek sprawdzany jest na końcu, i pętla wykonywana
jest tak długo, jak długo warunek nie jest spełniony.
while warunek
do
done
until warunek
do
done
Przykłady:
let x=0
while [[ $x -lt 10 ]]
do
echo x = $x
(( x=x+1 ))
done
while : # Pętla nieskończona, która nic nie robi
do
:
done
W liście komend występującej po słowie do można użyć komend
break - przerwanie pętli
continue - powrót do początku pętli
6.4. Funkcje
Ciąg poleceń można zdefiniować (np. na początku skryptu) jako funkcję,
a następnie wielokrotnie wykorzystywać tę funkcję w różnych miejscach skryptu
z różnymi parametrami. Funkcje można zdefiniować w jeden z następujących
sposobów:
function fname { lista; }
lub
gdzie fname jest nazwą funkcji.
Przykład:
function swapshvar
{ if [ $# != 2 ]
then
echo Zła liczba argumentów funkcji swapshvar
fi
eval tmp=\$$1
eval $1=\$$2
eval $2=\$tmp
}
x=XX; y=YY
a=AA; b=BB
swapshvar x y
swapshvar a b
echo x=$x, y=$y, a=$a, b=$b
W powyższym przykładzie funkcja swapshvar zamienia wartości dwóch
zmiennych powłoki, których nazwy są podane jako argumenty funkcji.
6.5. Inne konstrukcje powłoki
Listę komend można zamknąć w nawiasy okrągłe:
lub klamrowe
W pierwszym przypadku lista jest wykonywana w osobnym środowisku,
w drugim - w tym samym środowisku co powłoka macierzysta (opisywane konstrukcje
w powłoce Bourne'a maja nieco inne działanie).
Przykład:
$ pwd
/home/janek
$ (cd .. ; pwd)
/home
$ pwd
/home/janek
7. Przyporządkowanie strumieni we/wy
Przy otwarciu pliku jego dane pamiętane są w tablicy plików. Indeks
do tej tablicy nazywamy deskryptorem pliku. Zazwyczaj programy wykonujące
operacje wejścia/wyjścia określają plik lub urządzenie będące źródłem bądź
odbiorcą informacji nie poprzez nazwę pliku, ale przez deskryptor tego
pliku.
Następujące deskryptory są zarezerwowane:
0 standardowe wejście (standardowo związane z klawiaturą terminala),
1 standardowe wyjście (standardowo związane z monitorem terminala),
2 standardowe wyjście diagnostyczne (standardowo związane z
monitorem terminala).
Dzięki deskryptorom możliwa jest bardzo łatwa zmiana przyporządkowania
strumieni we/wy. Powłoka jest wyposażona w specjalne mechanizmy ułatwiające
takie operacje.
-
Zmiana standardowego wejścia:
Użycie tej konstrukcji spowoduje, że standardowym wejściem programu prog
będzie nie klawiatura terminala, ale plik o nazwie fname.
Konstrukcja (nazywana dokumentem wbudowanym, ang. here
document):
spowoduje, że linie od występującej bezpośrednio za komenda prog
aż do linii EOF będą standardowym wejściem dla komendy
prog. EOF może być dowolnym ciągiem znaków, ważne
jest jedynie by do zakończenia dokumentu wbudowanego użyć tego samego ciągu
znaków, którego użyto po podwójnym znaku mniejszości.
-
Zmiana standardowego wyjścia:
Użycie tej konstrukcji spowoduje, że standardowym wyjściem programu
prog będzie nie ekran monitora, ale plik o nazwie fname.
Zamiast pojedynczego można użyć podwójnego znaku większości:
Spowoduje to, że standardowe wyjście programu prog zostanie dopisane
na końcu pliku fname.
-
Zmiana standardowego wyjścia diagnostycznego:
Użycie tej konstrukcji spowoduje, że standardowe wyjściem diagnostyczne
programu prog będzie skierowane do pliku o nazwie fname.
Opisany powyżej mechanizm zmiany przypisania standardowych strumieni wejścia/wyjścia
można stosować do strumieni opisanych dowolnymi deskryptorami, np. zapis:
oznacza, że wejściem komendy prog będzie plik o deskryptorze d1,
a jego wyjściem - plik o deskryptorze d2. Często stosowaną konstrukcją
jest:
Konstrukcja taka oznacza, że standardowe wyjście (deskryptor 1
można tu opuścić) będzie skierowane do pliku fname, a standardowe
wyjście diagnostyczne - tam gdzie wskazuje deskryptor 1, zatem
także do pliku fname.
8. Skrypty
Przy pisaniu skryptów, które maja być wykonywane przez powłokę, należy
pamiętać o kilku sprawach.
-
Jeśli chcemy wykonać skrypt podobnie jak każdą inną komendę, tj. przez
napisanie nazwy skryptu z listą parametrów, to skrypt taki winien mieć
nadany atrybut x. Skrypt można wykonać także w następujący sposób:
(oczywiście zamiast sh można użyć nazwy innej powłoki). W obu
przypadkach skrypt zostanie wykonywane w osobnej powłoce. Oznacza to m.in.
że w czasie wykonywania skryptu nie będą widoczne niewyeksportowane wcześniej
zmienne powłoki, a zmienne zdefiniowane wewnątrz skryptu znikną po zakończeniu
wykonywania się skryptu.
-
Skrypt może być wykonany w ramach aktualnej powłoki za pomocą specjalnej
komendy . (kropka):
W ten sposób można wykonać także skrypt, któremu nie nadano atrybutu
x.
-
Parametry przekazywane w linii komendy są dostępne wewnątrz skryptu jako
zmienne powłoki $1, $2, ... itd. Użycie wewnątrz skryptu
komendy
spowoduje przesunięcie o jedną pozycję, tj. $1 będzie drugim
argumentem z linii komendy, $2 - trzecim itd.
-
Programista tworzący skrypt może narzucić powłokę, która ma wykonać skrypt.
Winien w tym celu podać w pierwszej linii nazwę tej powłoki (pełną ścieżkę
dostępu) poprzedzona znakami "magicznymi" #!, np.:
9. Konfiguracja powłoki
Niektóre aspekty sposobu działania powłoki można zmieniać za pomocą tzw.
przełączników powłoki. Przełączniki takie są ustawiane za pomocą
komendy
set +o opcja
set -o opcja
(znak + oznacza wyłączenie przełącznika opcja, znak -
jego włączenie). Liczba i znaczenie przełączników są zależne od powłoki.
Ważniejsze przełączniki to:
allexport
automatyczne eksportowanie zmiennych powłoki
ignoreeof
ignorowanie Ctrl-D (do zakończenia pracy konieczna jest komenda exit)
noexec
sprawdzana jest poprawność syntaktyczna komend (bez ich wykonania)
noglob
powłoka nie wykonuje generacji nazw plików
nounset
użycie niezdefiniowanej zmiennej powłoki jest traktowane jako błąd
monitor
pozwala na użycie komend sterowania zadaniami
W powłoce Bourne'a komenda set akceptuje jedynie jednoznakowe kody przełączników
(por. man pages).
Administrator systemu bądź użytkownik może utworzyć skrypty startowe,
tj. skrypty zawierające komendy, które maja być automatycznie wykonane
po zalogowaniu się użytkownika (rozpoczęciu pracy powłoki). Skrypty takie
mają ustalone w danej powłoce nazwy. Poniżej wymieniono pliki, które są
wykonywane po zalogowaniu przez powłoki Bourne'a, Korna i zsh.
Powłoka Bourne'a:
/etc/profile
$HOME/.profile
Powłoka Korna:
/etc/profile
$HOME/.profile
$ENV
Powłoka zsh:
/etc/zprofile
$HOME/.zprofile
$HOME/.zshenv
$HOME/.zshrc
$HOME/.zlogin
Pliki znajdujące się w katalogu /etc są tworzone przez administratora
i zwykły użytkownik nie ma na nie wpływu. Zawierają one zwykle komendy,
które muszą być wykonane podczas logowania się każdego użytkownika, takie
jak np. wyświetlenie motd, ustawienie ścieżki systemowej czy sprawdzenie
poczty. Pozostałe skrypty są tworzone przez użytkownika w jego prywatnym
katalogu i z reguły ustawiają parametry powłoki odnoszące się do tego użytkownika,
np. rodzaj terminala, prywatne katalogi w ścieżce dostępu, nazwa używanego
edytora ASCII, aliasy itp. Pliki $HOME/.profile ($HOME/.zprofile,
$HOME/.zlogin) wykonywane są (podobnie jak pliki z katalogu /etc)
tylko przez powłokę loginową, pliki wskazywane przez zmienną powłoki ENV
(lub plik $HOME/.zshenv w przypadku powłoki zsh) - jeśli
taka zmienna została zdefiniowana przez użytkownika - są wykonywane przez
każdą nowo uruchamianą przez użytkownika powłokę.
Edycja linii komendy
Przy wprowadzaniu poleceń z linii komendy często zachodzi potrzeba wprowadzenia
zmian i poprawek. Niestety, sposób edycji linii komendy jest rożny w różnych
powłokach. Najmniejsze możliwości w tym względzie ma powłoka Bourne'a,
gdzie możliwości edycji ograniczają się do skasowania kilku ostatnio wprowadzonych
znaków lub całej linii, i ponownego wprowadzenie na to miejsce poprawionego
tekstu.
Powłoki Korna i zsh pozwalają na edycję linii komendy w podobny
sposób, jak to się robi w edytorach vi lub emacs. Użytkownik
winien przypisać zmiennej powłoki EDITOR wartość odpowiadającą preferowanemu
edytorowi (tj. EDITOR=vi lub EDITOR=emacs). Od tego momentu
użytkownik może używać poleceń odpowiedniego edytora do wprowadzania zmian
w linii komendy. Możliwe jest także:
-
przywoływanie poprzednio wydanych poleceń,
-
automatyczne uzupełnianie przez powłokę nazwy pliku lub katalogu po napisaniu
przez użytkownika kilku pierwszych znaków nazwy tego pliku/katalogu (jeśli
znaki te pozwalają w sposób jednoznaczny określić, o jaki plik chodzi).
Jedna z bardziej cenionych zalet powłoki zsh jest możliwość manipulacji
kursorem w obrębie edytowanej linii komendy za pomocą klawiszy kursora,
w sposób podobny do edytora linii komendy z niektórych wersji systemu MS-DOS.
ES