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