Narzędzia użytkownika

Narzędzia witryny


materialy:podstawy-administracji:shell

Powłoka systemowa Bash

Wstęp

W systemie Linux jest wiele tzw. powłok systemowych, czyli programów w których administratorzy systemu wpisują komendy i realizują swoje codzienne zadania. Powłoki systemowe różnią się między sobą. Ta najbardziej popularna - Bash - jest instalowana na większości dystrybucji i początkującemu administratorowi będzie łatwiej z niej korzystać niż z innych z racji dostępu do wielu informacji i przykładów użycia w Internecie.

Poniższe zagadnienia są przedstawione w oparciu o powłokę Bash.

Zmienne środowiskowe

Zmienne środowiskowe (environment variables) są wykorzystywane przez różne systemy operacyjne, również przez Linux. Definiowane w czytelny sposób: ZMIENNA=wartość służą programom, procesom i skryptom aby miały informacje o tym jak skonfigurowane jest środowisko w którym są uruchamiane. Najbardziej popularną zmienną środowiskową jest zmienna PATH, której wartością jest lista katalogów w których znajdują się programy i skrypty uruchomieniowe w systemie. Dzięki tej zmiennej użytkownicy powłoki nie muszą wpisywać pełnej ścieżki do programu /bin/ls aby wyświetlić zawartość aktualnego katalogu, wystarczy ls, bo w zmiennej PATH zapewne znajdzie się katalog /bin/.

Aby wyświetlić aktualnie przypisaną wartość zmiennej, np. PATH należy użyć znaku $ przed zmienną:

echo $PATH

Aby przypisać wartość nowej zmiennej lub nadpisać wartość istniejącej zmiennej:

MOJAZMIENNA="wartosc"

Proszę zwrócić uwagę, że w systemie nie ma potrzeby deklarowania zmiennych, system również nie ostrzega przed potencjalnym nadpisaniem istniejącej już zmiennej.

Aby dopisać do istniejącej zmiennej jakąś wartość, np. katalog z binariami w katalogu domowym ~/bin do zmiennej PATH:

PATH=$PATH:~/bin

Wspominaliśmy, że zmienne służą programom aby miały wiedzę o tym w jakim środowisku pracują. Przykładowo, zmienna VISUAL może zmienić domyślny edytor, który jest używany dla crontab -e. Zmienna HOME określa jaki jest aktualny katalog domowy użytkownika - wykorzystywany jest na przykład przy komendzie cd ~. Zmienna LANG pozwala programom rozpoznać, w jakim języku ma być prezentowany interfejs oraz komunikaty.

Popularne zmienne środowiskowe i ich znaczenia
Zmienna Znaczenie
BASHPID PID aktualnie używanej powłoki Bash, można również użyć $$
HOME Katalog domowy użytkownika
HISTFILE Nazwa pliku z historią komend
HISTSIZE Liczba komend do zapamiętania przez narzędzie history
HOSTNAME Nazwa systemu
LANG Sposób kodowania znaków, używany język
MAIL Ścieżka do katalogu z pocztą użytkownika (spool dir)
PATH Lista katalogów z programami i skryptami uruchomieniowymi
PS1 Definicja znaku zachęty (prompt)
PWD Katalog w którym pracujesz
SHELL Aktualnie używana powłoka systemowa
UID ID użytkownika
USER Nazwa użytkownika

Zakres życia zmiennej środowiskowej zdefiniowanej przy pomocy ZMIENNA=wartość jest ograniczony do uruchomionej powłoki. Przykład:

[root@centosm02 ~]# MOJ=test
[root@centosm02 ~]# echo $BASHPID
1506
[root@centosm02 ~]# echo $MOJ
test
[root@centosm02 ~]# bash
[root@centosm02 ~]# echo $BASHPID
1585
[root@centosm02 ~]# echo $MOJ

[root@centosm02 ~]# exit
[root@centosm02 ~]# echo $BASHPID
1506
[root@centosm02 ~]# echo $MOJ
test

Wystarczy uruchomić kolejną powłokę bash aby zmienna środowiskowa „zniknęła”. Tak na prawdę ona nie znika, tylko w nowym środowisku Bash nie została zdefiniowana. W przykładzie powyżej posługujemy się zmienną środowiskową BASHPID aby pokazać, że komendy są uruchamiane w różnych powłokach (różne identyfikatory procesów). Rozwiązaniem na tą niedogodność jest użycie komendy export.

Zmieniona zmienna środowiskowa lub nowo zdefiniowana „znika” również gdy użytkownik zakończy pracę w powłoce - wyloguje się. Aby móc operować na zmodyfikowanych lub nowych zmiennych po zalogowaniu należy odpowiednio skonfigurować skrypty startowe powłoki systemowej, opisene niżej.

export

Aby zmienna była używana w procesach potomnych (innych powłokach, programach, skryptach itp.) należy przed definicją zmiennej użyć komendy export:

[root@centosm02 ~]# export MOJ=test
[root@centosm02 ~]# echo $BASHPID
1506
[root@centosm02 ~]# echo $MOJ
test
[root@centosm02 ~]# bash
[root@centosm02 ~]# echo $BASHPID
1585
[root@centosm02 ~]# echo $MOJ
test

Użycie komendy export bez parametrów wyświetli wszystkie zmienne, które będą exportowane do procesów potomnych.

readonly

Aby zabezpieczyć się przed modyfikacją zmiennej można oznaczyć ją jako tylko do odczytu:

root@debiansrv02:~# MOJ=test
root@debiansrv02:~# readonly MOJ
root@debiansrv02:~# MOJ=nowawartosc
bash: MOJ: zmienna tylko do odczytu

Uruchomienie komendy readonly bez parametrów wyświetli listę aktualnie zdefiniowanych zmiennych środowiskowych tylko do odczytu.

env

Aby uruchomić program lub skrypt w zmodyfikowanym środowisku (z innymi zmiennymi środowiskowymi) można użyć komendy env. Wcześniej zdefiniowana i wyeksportowana zmienna MOJ powinna być używana w procesach potomnych. Możemy jej nie używać w procesie potomnym, jeśli wywołamy go z użyciem komendy env z odpowiednim parametrem: env -u MOJ:

root@debiansrv02:~# echo $BASHPID
4423
root@debiansrv02:~# export MOJ=test
root@debiansrv02:~# export | grep MOJ
declare -x MOJ="test"
root@debiansrv02:~# bash
root@debiansrv02:~# echo $BASHPID
4435
root@debiansrv02:~# echo $MOJ
test
root@debiansrv02:~# exit
exit
root@debiansrv02:~# echo $BASHPID
4423
root@debiansrv02:~# env -u MOJ bash
root@debiansrv02:~# echo $BASHPID
4441
root@debiansrv02:~# echo $MOJ

root@debiansrv02:~# 

Za pomocą env można też zdefiniować nowe lub modyfikować istniejące zmienne środowiskowe:

root@debiansrv02:~# echo $BASHPID
4423
root@debiansrv02:~# env MOJ=testenv PATH=/usr/bin /bin/bash
root@debiansrv02:~# echo $BASHPID
4509
root@debiansrv02:~# echo $MOJ
testenv
root@debiansrv02:~# echo $PATH
/usr/bin
root@debiansrv02:~# exit
exit
root@debiansrv02:~# echo $BASHPID
4423
root@debiansrv02:~# echo $MOJ
test
root@debiansrv02:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root@debiansrv02:~# 

set

Komenda set wbudowana w Bash uruchomiona bez parametrów wyświetla listę zdefiniowanych zmiennych środowiskowych. Uruchomiana z użyciem przełącznika -o pozwala na zmiany kilku parametrów powłoki Bash.

Komenda Działanie
set +o history
Wyłącz zapamiętywanie uruchamianych komend w historii
set -o history
Włącz zapamiętywanie uruchomionych komend w historii
set -o allexport
Włącz automatyczny export wszystkich definiowanych zmiennych (nie wymaga osobnego używania komendy export)
set +o allexport
Wyłączenie opcji allexport

Pełna lista parametrów:

set -o

unset

Komenda unset pozwala na usunięcie ze środowiska zdefiniowanej wcześniej zmiennej.

[root@centosm02 ~]# MOJAZMIENNA=jakaswartosc
[root@centosm02 ~]# echo $MOJAZMIENNA
jakaswartosc
[root@centosm02 ~]# unset MOJAZMIENNA
[root@centosm02 ~]# echo $MOJAZMIENNA

[root@centosm02 ~]#

Prompt

Po uruchomieniu Bash (najczęściej po zalogowaniu do systemu w trybie tekstowym) pojawia się znak zachęty (prompt), czyli dynamicznie generowany tekst, który będzie pojawiał się przed kursorem przy oczekiwaniu na wpisanie komendy przez użytkownika. Niezależnie jakiej dystrybucji używasz znak zachęty można zmienić w bardzo szerokim zakresie.

Zmienna środowiskowa, która definiuje jak ma wyglądać prompt to PS1. Aby zobaczyć jak wygląda obecna definicja zachęty:

echo $PS1

Przed jakimikolwiek zmianami i testowaniem nowo zdefiniowanych tekstów w prompt dobrze jest wykonać backup obecnej definicji, na przykład poprzez zdefiniowanie nowej zmiennej:

PS1BACKUP=$PS1

Przy budowie własnej zachęty dobrze się trzymać przynajmniej jednej podstawowej zasady: użytkownik root powinien mieć w znaku zachęty znak #, natomiast zwykły użytkownik $. Jest to zasada, która pozwoli administratorowi na szybą ocenę, czy pracuje z uprawnieniami zwykłego użytkownika (bezpieczniejsze) czy w kontekście roota i musi, szczególnie w środowisku produkcyjnym, bardziej uważać na wpisywane polecenia do systemu.

Wyświetlając aktualną definicję promptu widać, że składa się on z kodów znakowych, przykładowo:

  • \H - nazwa hosta
  • \u - nazwa użytkownika
  • \t - aktualna godzina z dokładnością do sekundy

Opis wszystkich kodów można znaleźć w dokumentacji bash man bash w sekcji PROMPTING.

Przykładowo, aby uzyskać prompt [weronika@serwer-a 11:37:50 bin]$ składający się z nazwy konta użytkownika, znaku małpy, nazwy hosta, godziny i aktualnego katalogu w którym znajduje się użytkownik należy zdefiniować taką wartość zmiennej PS1:

PS1="[\u@\H \t \W]$ "

W budowaniu własnych znaków zachęty, oprócz dokumentacji, pomocna może być strona Easy Bash Prompt Generator.

Skrypty startowe powłoki systemowej Bash

Skrypty startowe powłoki Bash przy logowaniu do systemu

Konta użytkowników mają przypisane domyślną powłokę, która jest uruchamiana przy starcie systemu. Administrator definiuje ten parametr przy zakładaniu konta użytkownika (useradd), choć może to później zmienić:

usermod -s /bin/bash isabelle

Siódme pole pliku /etc/passwd definiuje domyślną powłokę dla użytkownika:

grep ^isabelle /etc/passwd | cut -f7 -d:

Jeśli użytkownik ma ustawioną domyślną powłokę na /bin/bash to po zalogowaniu, zaraz przed tym jak pojawi się znak zachęty, uruchamiane są skrypty startowe powłoki:

Skrypt startowy przy logowaniu kolejność uruchamiania znaczenie
/etc/profile 1 globalny plik, jego modyfikacja wpływa na wszystkie konta systemowe, może uruchamiać inne skrypty startowe
~/.bash_profile 2 Plik zamieszczony w katalogu domowym użytkownika
~/.bash_login 3 Plik zamieszczony w katalogu domowym użytkownika i uruchomiony tylko wtedy, gdy nie ma ~/.bash_profile
~/.profile 4 Plik zamieszczony w katalogu domowym użytkownika i uruchomiony tylko wtedy, gdy nie ma ~/.bash_profile i ~/.bash_login
Skrypt używany przy wylogowaniu
~/.bash_logout 999 Plik zamieszczony w katalogu domowym użytkownika i uruchamiany zaraz przed jego wylogowaniem z systemu (po wywołaniu przez niego komendy exit)

Wiele dystrybucji różni się w konfiguracji skryptów, dlatego też w różnej kolejności mogą być one uruchamiane:

Skrypt startowy przy logowaniu kolejność uruchamiania w CentOS 6 znaczenie
/etc/profile 1 globalny plik, jego modyfikacja wpływa na wszystkie konta systemowe
/etc/profile.d/*.sh 2 zestaw plików globalnych, zazwyczaj dodawanych przez paczki instalacyjne oprogramowania; po zalogowaniu uruchamiane są wszystkie skrypty z tego katalogu, które mają rozszerzenie .sh; skrypty te wywoływane są przez skrypt /etc/profile
~/.bash_profile 3 Plik zamieszczony w katalogu domowym użytkownika
~/.bashrc 4 Plik zamieszczony w katalogu domowym użytkownika i uruchamiany przez skrypt ~/.bash_profile
/etc/bashrc 5 Plik globalny, uruchamiany przez ~/.bashrc użytkownika
Skrypt startowy przy logowaniu kolejność uruchamiania w Debian znaczenie
/etc/profile 1 globalny plik, jego modyfikacja wpływa na wszystkie konta systemowe
/etc/bash.bashrc 2 Plik globalny, uruchamiany przez /etc/proflie użytkownika
/etc/profile.d/*.sh 3 zestaw plików globalnych, zazwyczaj dodawanych przez paczki instalacyjne oprogramowania; po zalogowaniu uruchamiane są wszystkie skrypty z tego katalogu, które mają rozszerzenie .sh; skrypty te wywoływane są przez skrypt /etc/profile
~/.profile 4 Plik zamieszczony w katalogu domowym użytkownika
~/.bashrc 5 Plik zamieszczony w katalogu domowym użytkownika i uruchamiany przez skrypt ~/.profile

Skrypty startowe powłoki Bash dla nie-interaktywnego uruchomienia Bash

Bash może być uruchomiony nie tylko podczas logowania ale również jako kolejna powłoka w już uruchomionej powłoce (podproces):

[root@centosm02 ~]# echo $BASHPID
2438
[root@centosm02 ~]# bash
[root@centosm02 ~]# echo $BASHPID
2463
[root@centosm02 ~]# 

W powyższym przypadku mówi się o nie-interaktywnym uruchomieniu Bash i związany on jest z uruchomieniem innego zestawu skryptów - przede wszystkim nie są wtedy uruchamiane skrypty /etc/profile, ~/.bash_login, ~/.profile i ~/bash_profile.

Skrypt startowy przy uruchamianiu nie-interaktywynym Bash kolejność uruchamiania w CentOS znaczenie
.bashrc 1 Plik zamieszczony w katalogu domowym użytkownika
/etc/bashrc 2 Pliki globalny dla wszystkich użytkowników, uruchamiany przez .bashrc
/etc/profile.d/*.sh 3 zestaw plików globalnych, zazwyczaj dodawanych przez paczki instalacyjne oprogramowania; po uruchomieniu Bash uruchamiane są wszystkie skrypty z tego katalogu, które mają rozszerzenie .sh
Skrypt startowy przy uruchamianiu nie-interaktywynym Bash kolejność uruchamiania w Debian znaczenie
/etc/bash.bashrc 1 Plik globalny
.bashrc 2 Plik zamieszczony w katalogu domowym użytkownika

Wykorzystanie skryptów startowych do definiowania zmiennych środowiskowych, aliasów itp.

Fakt uruchamiania różnych skryptów startowych przy uruchamianiu Bash powoduje, że administrator lub użytkownik edytując je może modyfikować środowisko w którym uruchamiane są programy i skrypty.

Przykładowo, jeśli użytkownik chce zawsze używać aliasu wolnemiejsce może dopisać na końcu pliku ~/.bashrc linię

alias wolnemiejsce='df -h .'

aby po zalogowaniu alias ten był zawsze dostępny.

Aby zdefiniować nowe zmienne środowiskowe lub zmodyfikować istniejące (np. PATH) może dokonać edycji pliku .bash_profile (CentOS) lub .profile (Debian).

Skrypty startowe wgrywane na nowo tworzone konto użytkownika

Pliki .bashrc, .profile czy inne tworzone są automatycznie w katalogu domowym użytkownika przy tworzeniu jego konta (komenda useradd). Administrator jednak nie musi pamiętać o konieczności kopiowania tam tych plików i nadawania im odpowiednich uprawnień. Katalog /etc/skel zawiera listę plików, które są automatycznie kopiowane do katalogu domowego nowo tworzonego konta:

[root@centosm02 ~]# ls -la /etc/skel
razem 20
drwxr-xr-x.  2 root root 4096 11-16 11:08 .
drwxr-xr-x. 61 root root 4096 05-04 01:55 ..
-rw-r--r--.  1 root root   18 2013-02-21  .bash_logout
-rw-r--r--.  1 root root  176 2013-02-21  .bash_profile
-rw-r--r--.  1 root root  124 2013-02-21  .bashrc
[root@centosm02 ~]# useradd -m testowyuser
[root@centosm02 ~]# ls -la /home/testowyuser
razem 20
drwx------. 2 testowyuser testowyuser 4096 05-04 01:56 .
drwxr-xr-x. 4 root        root        4096 05-04 01:56 ..
-rw-r--r--. 1 testowyuser testowyuser   18 2013-02-21  .bash_logout
-rw-r--r--. 1 testowyuser testowyuser  176 2013-02-21  .bash_profile
-rw-r--r--. 1 testowyuser testowyuser  124 2013-02-21  .bashrc

Aliasy

Powłoka Bash pozwala na tworzenie aliasów, czyli innych nazw na znane już komendy. Alias pozwala nie tylko na nowe nazwanie starej komendy ale również na użycie dodatkowych parametrów. Przykłady:

carlos@debiansrv02:~$ df -h .
System plików                rozm. użyte dost. %uż. zamont. na
/dev/mapper/debiansrvXX-home  2,7G   69M  2,5G   3% /home
carlos@debiansrv02:~$ wm
-su: wm: nie znaleziono polecenia
carlos@debiansrv02:~$ alias wm='df -h .'
carlos@debiansrv02:~$ wm
System plików                rozm. użyte dost. %uż. zamont. na
/dev/mapper/debiansrvXX-home  2,7G   69M  2,5G   3% /home
carlos@debiansrv02:~$ 

Alias może również zmodyfikować działanie domyślnych parametrów dowolnej komendy:

carlos@debiansrv02:~$ ls
abrakadabra.txt  skrypt.sh
carlos@debiansrv02:~$ ls -l
razem 8
-rw-r--r-- 1 carlos carlos  7 kwi  7 14:35 abrakadabra.txt
-rwxr--r-- 1 carlos carlos 23 maj  3 15:43 skrypt.sh
carlos@debiansrv02:~$ alias ls='ls -l'
carlos@debiansrv02:~$ ls
razem 8
-rw-r--r-- 1 carlos carlos  7 kwi  7 14:35 abrakadabra.txt
-rwxr--r-- 1 carlos carlos 23 maj  3 15:43 skrypt.sh
carlos@debiansrv02:~$ 

Definicje aliasów „giną” po wylogowaniu z Bash. Należy zmodyfikować odpowiednie skrypty startowe powłoki Bash, aby aliasy były definiowane i dostępne po każdym logowaniu do systemu.

Użyj komendy alias bez parametrów aby wyświetlić wszystkie zdefiniowany aliasy w środowisku w którym pracujesz.

Funkcje

Funkcje podobnie do aliasów mogą ułatwić wywoływanie komend powtarzalnych a nawet zestawu komend. Choć używa się je głównie w skryptach, można je również uruchamiać w powłoce jako odseparowane komendy. Przykładowo definicja funkcji testowa i przypadek jej użycia:

[isabelle@centosm02 ~]$ function testowa() {
> ls -l ~/bin
> ls -la ~/
> }
[isabelle@centosm02 ~]$ testowa 
total 4
-rwxrw-r--. 1 isabelle isabelle 32 May  3 21:16 skrypt.sh
total 32
drwx------. 3 isabelle isabelle 4096 May  3 22:43 .
drwxr-xr-x. 3 root     root     4096 Apr 13 14:47 ..
-rw-------. 1 isabelle isabelle  811 May  3 21:56 .bash_history
-rw-r--r--. 1 isabelle isabelle   18 Feb 21  2013 .bash_logout
-rw-r--r--. 1 isabelle isabelle  213 May  3 20:45 .bash_profile
-rw-r--r--. 1 isabelle isabelle  155 May  3 20:45 .bashrc
drwxrwxr-x. 2 isabelle isabelle 4096 May  3 22:43 bin
-rw-------. 1 isabelle isabelle  143 May  3 21:40 .lesshst
[isabelle@centosm02 ~]$ 

Funkcje mają szczególne znaczenie przy skryptach, gdyż potrafią zwracać wartości, a więc mogą być używane w testach i instrukcjach warunkowych. Aby funkcje były dostępne po wylogowaniu, tak jak aliasy, muszą być zdefiniowane w skryptach startowych powłoki Bash.

Listy

Listy w Bash, inaczej zwane zmiennymi tablicowymi (ang. arrays), pozwalają przypisać jednej zmiennej tablicowej kilka wartości do których można odwołać się używając indeksu tablicy:

[isabelle@centosm02 ~]$ lista=(jeden dwa trzy)

Dla tak zdefiniowanej listy można wyświetlić poszczególne elementy (indeksowane od zera), wszystkie elementy, lub liczbę elementów w tablicy

[isabelle@centosm02 ~]$ echo ${lista[*]}
jeden dwa trzy
[isabelle@centosm02 ~]$ echo ${lista[0]}
jeden
[isabelle@centosm02 ~]$ echo ${lista[1]}
dwa
[isabelle@centosm02 ~]$ echo ${lista[2]}
trzy
[isabelle@centosm02 ~]$ echo ${lista[3]}

[isabelle@centosm02 ~]$ echo ${#lista[*]}
3
[isabelle@centosm02 ~]$ 

Aby przypisać do listy wynik innej komendy można użyć znaków ` do wywołania komendy w komendzie:

[isabelle@centosm02 ~]$ listauzytkownikow=(`cut -f1 -d: /etc/passwd`)
[isabelle@centosm02 ~]$ echo ${#listauzytkownikow[*]} 
21
[isabelle@centosm02 ~]$ echo ${listauzytkownikow[13]} 
ftp
[isabelle@centosm02 ~]$ 

Zadania

Zadania dla powyższego materiału znajdują się na osobnej stronie.


Masz potrzebę, aby powyższa strona była rozbudowana? - Napisz do nas!.

materialy/podstawy-administracji/shell.txt · ostatnio zmienione: 2015/02/15 19:31 przez mzalewski

(C) 2017 ITMZ Mariusz Zalewski