Spis treści
Bash jest jedną z powłok systemowych, czyli programów, które pośredniczą między systemem operacyjnym a użytkownikiem. Użytkownik za pomocą powłoki uruchamia programy, jak i programy zwracają do powłoki wynik swojego działania, który następnie jest przekazywany użytkownikowi. Programy mogą komunikować sie z użytkownikiem również niezależnie (np. programy okienkowe).
Każda powłoka zawiera polecenia, które wykonują podstawowe operacje w systemie operacyjnym (np. tworzenie folderów). Paletę domyślnych poleceń wzbogacają zewnętrzne programy, które wykonują operacje nie będące zawartymi poleceniami.
Praktycznie każda dystrybucja Linuxa (z Androidem włącznie) zawiera powłokę Bash.
Jednym z podstawowych poleceń jest echo, służące do wyświetlania tekstu podanego mu jako argument:
echo foo
foo
W poleceniu echo możemy również stosować tzw. metaznaki. Przykładem takiego znaku jest *:
cd /
echo *
bin boot dev etc home initrd.img initrd.img.old lib lib32 lib64 lost+found media mnt opt optl proc root run sbin selinux srv sys tmp usr var vmlinuz vmlinuz.old
echo b*
bin boot
W powyższym przykładzie widzimy, że Bash rozwija znak * zastępując go dowolnym ciągiem znaków.
Innym przykładem metaznaku jest ~, który zastępuje katalog domowy.
echo ~
/home/jb
Za pomocą polecenia echo wyświetlić wszystkie pliki kończące się na .conf z katalogu /etc
W systemie Linux dane mogą być wprowadzane z następujących źródeł:
Program może wysyłać wynik swonego działania w takie miejsca:
Schemat działania programu.
Filtr to specjalny rodzaj programu linuskowego, który pobiera dane (tylko) ze standardowego wejśca i zapisuje je (tylko) na standardowe wyjście.
Schemat działania filtru.
Program cat odczytuje zawartość plików i przekierowuje ją na standardowe wyjście:
cat nazwa_pliku
By przekierować standardowe wyjście programu do pliku należy użyć operatora > lub >>.
cat plik1 plik2 >> polaczonepliki
W wariancie z > polecenie to spowoduje nadpisanie pliku zawartością standardowego wyjścia, w wariancie >> spowoduje dopisanie treści na końcu pliku.
Załóżmy, że mamy dwa polecenia: polecenieB i polecenieB i chcemy, aby polecenieB na swoje standardowe wejście przyjęło wynik działania polecenieA. W takim przypadku należy wpisać:
polecenieA | polecenieB
Inne przykładowe filtry:
tail
Pokazuje koncówkę pliku
cat /usr/share/romeo | tail -n 100
head
Pokazuje początek pliku
Każdy program ma podłączone dwa standardowe strumienie wyjściowe:
Rozróżnienie wynika z tego, aby wynik działania programu mógł być zwracany przez jeden strumień (np. polecenie tar zwróci spakowany folder), a informacje o ewentualnych błędach przez inny strimień.
By przekierować standardowy strumień błędów należy użyć 2> lub 2>>.
Proszę pobrać tekst Romeo i Julii po angielsku /downloads/pg1112.txt
wget http://www.gutenberg.org/cache/epub/1112/pg1112.txt
Po kolei należy:
Proszę wylistować użytkowników z pliku /etc/passwd za pomocą polecenia cut.
Note
Polecenie cut służy do wypisywania wybranych części (elementów) linii z pliku tekstowego. W naszym przypadku używamy to polecenie z opcją -d :, która powoduje, że linie dzielone są na części odseparowane od siebie znakiem :. Użycie opcji -f 1 wybiera 1 część (z 2 drugą część, itd.)
Proszę skompresować wybrany katalog do formatu tar.bz2 za pomocą polecenia tar. Następnie folder wypakować.
Note
W obu przypadkach należy użyć polecenie tar z odpowiednimi opcjami.
Plik /dev/null to plik, który przyjmuje dowolne dane, które potem znikają.
Jest on przydatny kiedy chcemy się pozbyć jakiegoś strumienia danych (np. komunikatów o błędach).
polecenie 2> /dev/null
Plik /dev/random oraz /dev/urandom zawierają nieskończone ciągi losowych liczb.
Taka komenda pozwala na wpipsanie kilku losowych znaków:
cat /dev/urandom | head -c 66 | base64
Sygnały są metodą na komunikację między procesami w systemach Linux’owych. Pozwalają, na przykład, na:
Do wysyłania sygnałów służą polecenia oraz pkill, kill.
Polecenie kill przyjmuje id procesu, polecenie pkill wysyła sygnał do procesów, których nazwa zawiera ciąg znaków podanych w tym poleceniu.
jb /tmp/bar $ ps -e | grep iceweasel
5020 ? 00:13:16 iceweasel
kill 5020
To samo zadanie wykona:
pkill iceweasel
Domyślnie pkill i kill wysyłają sygnał TERM, który prosi proces by ten się wyłączył (proces może się na to nie zgodzić).
Polecenia pkill -9 oraz kill -9 pozwalają na zabicie procesu (proces zawsze się wyłączy).
Polecenie pkill --signal SIGSTOP spowoduje wstrzymanie wykonania procesu, a pkill --signal SIGCONT włączy go ponownie.
Proszę uruchomić przeglądarkę iceweasel, wstrzymać ją a następnie wznowić jej proces.
W katalogu /proc zawarte są dane o wszystkich procesach w Linux’ie, w katalogu /proc/1234 są dane o procesie o id równym 1234, w tym katalogu jest plik status zawierający informacje o procesie.
Note
Opis zawartości /proc można poznać wpisując:
Plik status ma zawartość podobną do:
Name: cat
State: R (running)
Tgid: 5556
Pid: 5556
PPid: 5555
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 64
Groups: 0
VmPeak: 5824 kB
VmSize: 5824 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 360 kB
VmRSS: 360 kB
VmData: 176 kB
VmStk: 136 kB
VmExe: 44 kB
VmLib: 1808 kB
VmPTE: 28 kB
VmSwap: 0 kB
Threads: 1
SigQ: 1/125663
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000001fffffffff
CapEff: 0000001fffffffff
CapBnd: 0000001fffffffff
Seccomp: 0
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 0
nonvoluntary_ctxt_switches: 1
Nas interesuje pole VmSize zawierające rozmiar pamięci używanej przez program proszę napisać linijkę kodu, która będzie wyświetlać rozmiar pamięci zajmowanej przez program, tj. dla procesu z przykładu wyświetli:
5824 kB
Wskazówki:
W Bash’u można również tworzyć zmienne.
jb@gautama:/$ foo="bar";
jb@gautama:/$ echo $foo;
bar
jb@gautama:/$ echo ${foo}; #Równoważne do $foo
bar
Uwaga: Białe znaki mają znaczenie: tj. poniższy kod jest niepoprawny: foo = "bar"
Export powoduje, że zmienne są dostępne dla podprocesów.
export foo="bar";
Nie ma możliwości udostępnienia zmiennych dla nadprocesów.
By ustawić zmienne środowiskowe ‘na stałe’ należy umieścić odpowiednie polecenia export w plikach:
Zmienna path jest magiczną zmienną powłoki BASH, pozwala ona na zdefiniowanie w jakich katalogach bash szuka plików wykonywalnych.
Note
Zmienna $PATH określa listę katalogów, które będą przeszukiwane podczas uruchamiania programu.
Jeśli $PATH to /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games oznacza to, że po wykonaniu polecenia np. nano zostaną przeszukane takie położenia: /usr/local/bin/nano, /usr/bin/nano. itp.
Wszystkie zmienne środowiskowe można wyświetlić za pomocą polecenia printenv.
Proszę ustawić zmienną PATH na pusty ciąg znaków i sprawdzić jakie polecenia działają.
Czy działa:
Polecenia, które działają są wbudowanymi poleceniami powłoki bash, pozstałe są programami.
Powiedzmy, że mamy katalog o nazwie Moje Dokumenty, który znajduje się w bieżącym katalogu. Chcemy go usunąć, jednak nie udaje się to:
rm Moje Dokumenty
rm: cannot remove ‘Moje’: No such file or directory
rm: cannot remove ‘Dokumenty’: No such file or directory
Okazuje się, że bash potraktował Moje Dokumenty jako dwa katalogi, jeden o nazwie Moje, drugi o nazwie Dokumenty.
By usunąć ten plik należy użyć cytowania, czyli powiedzieć bashowi: ten ciąg znaków ze spacją jest jednym słowem, służą do tego podwójne cudzysłowy.
Taka komenda zadziała:
rm "Moje Dokumenty"
Powiedzmy, że nasz skrypt chce wyświetlić użytkownikowi napis: Dodaj katalog foo do zmiennej ${PATH}.
Polecenie:
echo "Dodaj katalog foo do zmiennej ${PATH}"
wyświetli:
Dodaj katalog foo do zmiennej /usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Znów musimy zacytować nasz ciąg znaków, ale tym razem trzeba użyć pojedyńczego apostrofu:
echo 'Dodaj katalog foo do zmiennej ${PATH}'
Wyświetla:
Dodaj katalog foo do zmiennej ${PATH}
Skrypty bash mogą być uruchamiane tak samo jak zwykłe programy, o ile:
Przykład najprostszego skryptu:
#!/bin/bash
echo hello ze skryptu
Napisać skrypt, który wypisze 3 linijki:
Czasem chcemy zapisać wynik polecenia do zmiennej, np. polecenie date wyświetla do wyświetlania daty służy polecenie date:
date +%Y-%m-%d
wyświetla:
2015-10-05
Chcemy stworzyć plik o nazwie kopia-zapasowa-data:
curr_date=$(date +%Y-%m-%d)
file_name="kopia-zapasowa-${curr_date}"
echo > $file_name
można to zrobić prościej:
touch "kopia-zapasowa-$(date +%Y-%m-%d)"
Note
Uwaga! Działanie $() można osiągnść również poprzez zastosowanie odwróconych cudzysłowów (`), tj:
touch "kopia-zapasowa-`date +%Y-%m-%d`"
Jednak by oszczędzić Wam problemów z , ‘ oraz ”, będę wykorzystywał ``$()`.
Skrypt basha zawiera specjalne zmienne:
Napisać skrypt (i uruchomić z 3. dowolnymi argumentami), który:
Wykonanie każdego programu może skończyć się albo sukcesem, albo porażką, do syngalizowania sukcesu lub porażki służy tzw. kod wyjścia.
Note
W C kod wyjścia programu jest sygnalizowani (między innymi) wartością zwracaną przez funkcję main.
Jeśli program wykonmał się poprawnie funkcja zwraca 0, jeśli nie poprawnie inną wartość.
Note
Jest to notacja odwrotna od tej stosowanej w C, tam 0 oznacza fałsz, a 1 prawdę.
Powód takiej notacji w jest prosty: Program może poprawnie się wykoanć tylko w jeden sposób, może natomiast napotkać na wiele problemów, które spowodują błędne wykonanie.
Do sprawdzenia kodu wyjścia ostatniego polecenia można użyć magicznej zmiennej $?.
Instrukcja if w Bash ma następującą składnię:
if warunek
then
fi
Gdzie warunek jest dowolnym programem. Jeśli program ten zwróci kod wyjścia 0 warunek się wykona, nie wykona się natomiast jeśli zwróci inny kod wyjścia.
Przykładowo by sprawdzić czy foo jest nazwą użytkownika można użyć:
if grep foo /etc/passwd > /dev/null
then
echo "Jest"
fi
Note
Uwaga zastosowałem tu nową składnię polecenia grep jest to składnia grep wzorzec nazwa pliku oraz przekierowałem wyjście z grep do pliku /dev/null.
Pełna składnia if jest taka:
if warunek1
then
polecenie1
elif warunek2
then
polecenie2
else
polecenie3
fi
W warunku if często korzysta się z polecenia test, na przykład test -e plik sprawdza czy plik istnieje:
if test -e /tmp/foo
then
echo istnieje
else
echo nie istnieje
fi
Polecam sprawdzenie jak działa polecenie test za pomocą man test.
Polecenie test można wykorzystać również za pomocą krótszej postacji, tj. nawiasów kwadratowych:
if [ -e /tmp/foo ]
then
echo istnieje
else
echo nie istnieje
fi
Uwaga: między [ oraz ], a warunkiem musi znajdować się przynajmniej jedna spacja.
Napisać skrypt, który:
sprawdzi czy istnieje plik ~/.xsession-errors i wypisze odpowiednią informację
porówna liczbę plików w katalogu głównym oraz domowym i wypisze odpowiednią informację
Note
Polecam program wc (proszę przeczytać man wc)
Do obliczeń arytmetycznych służy funkcja let:
let x=10
echo $x # wypisze 10
let "x /= 3"
echo $x # wypisze 3
let "x *= x"
echo $x # wypisze 9
Warning
Bash może wspierać tylko arytmetykę stałoprzecinkową, dla której 10/3 wynosi dokładnie 3.
Warning
Przy wykonywaniu operacji należy umieszczać spacje wokół operatora =.
Niektóre fragmenty skryptu można zamknąć w funkcję, składnia funkcji jest następująca:
function func {
# Treść
}
By wykonać funkcję należy napisać jej nazwę.
Do funkcji można przekazywać parametry. Parametry funkcji są dostępne za pomocą tych samych zmiennych co argumenty skyptu, tj:
Pętla for pozwala na iterowanie po zbiorze elementów separowanych spacją:
for i in a b c d
do
echo "wartość iteratora to $i"
done
for i in /etc/*conf
do
echo "$i"
done
Note
Można skonfigurować basha tak, by separatorem był inny znak, ale poprzestańmy na spacji.
while - sprawdza, czy warunek jest prawdziwy, jeśli tak, pętla wykonuje się, aż warunek stanie się fałszywy:
a=0
while [ $a -lt 5 ]
do
echo "pętla wykonuje się po raz: $a"
a=$[a + 1] # lub a=$(( $a + 1 ))
done
until - sprawdza, czy warunek jest fałszywy, jeśli tak, pętla wykonuje się aż warunek stanie się prawdziwy:
a=0
until [ $a -gt 5 ]
do
echo "pętla wykonuje się po raz: $a"
a=$[a + 1]
done
Napisz funkcję, która liczy silnię jej argumentu, wykonaj ją dla liczb od 1 do 15.
Wyrażenia regularne są narzędziem pozwalającym na:
Wyrażenia regularne są narzędziem pozwalają na definiowanie zbiorów ciągów znaków.
Znaki * oraz + powodują że poprzedni ciąg jest powtarczny, + oznacza jedno lub więcej powtórzenie, * zero lub więcej:
Nawiasy () służą do grupowania ciągów znaków:
Nawiasy [] służą do definiowania grup znaków:
Predefiniowane zestawy znaków:
By wybrać znak który normalnie pełni specjalną rolę w wyrażeniach regularnych (np. * lub nawias) należy postawić przed nim ukośnik \.
Znak | oznacza operator lub:
Polecenie sed jest bardzo potężnym “strumieniowym edytorem” tekstu, który polega na wyrażeniach regularnych, przykład:
echo 'samogłoski stają się kropkami' | sed 's/[aeouiy]/./g'
Sed przyjmuje ciąg znaków (jest on tutaj cytowany, ponieważ zawiera również specjalne znaki powłoki bash), ciąg ten ma taki format s/wyrażenie reg/zastępnik/g, gdzie wyrażenie reg jest wyrażeniem regularnym, którego wystąpienia zostaną zamienione na zastępnik.
Wyrażenia regularne obsługują również grupy znaków które są definiowane za pomocą zwykłych nawiasów. Przy zastępowaniu przez sed (i inne programy) w zastępniku mogą pojawiać się ciągi znaków w formacie \1, \2, \3, które zostaną zastąpione przez to co zostanie wybrane przez grupę o odpowiednim numerze:
echo 'zmiana . na , w liczbach rzeczywistych: 3.14' | sed 's/\([0-9]\+\)\.\([0-9]\+\)/\1,\2/g'
Wyrażenie to zawiera dwie grupy oddzielone kropką, pierwsza z nich wybiera ciąg znaków 3, druga 14, następnie do zastępnika w formacie \1,\2 podstawia te dwie grupy, co daje 3,14.
Proszę pobrać tekst Romeo i Julii po angielsku:
wget http://db.fizyka.pw.edu.pl/sk-2015/_downloads/pg1112.txt
echo
Zwraca linie poleceń na standardowe wyjście
echo foo bar baz;
Przenosi do innego katalogu.
cd /tmp;
cd ; # Przenosi do katalogu domowego
cd ~/foobar; # przenosi do katalogu foobar w katalogu domowyn
ls
Listuje zawartość katalogu
ls ; ls -al; #listuje wszystkie pliki z dodatkowymi informacjami ls -a1; #wszystkie pliki jeden na linię (do skryptów) ls /tmp; # listuje katalog tmo
mkdir
Tworzy katalog
mkdir /tmp/foo
cat
Otwiera wiele plików i przekierowuje je na standardowe wyjście
cat /usr/share/romeoandjuliet; cat *sql;
tail
Pokazuje koncówkę pliku
tail /usr/share/romeoandjuliet; tail -n 1000 /usr/share/romeoandjuliet;# Pokazuje ostatnich 1000 linii tail -f /usr/share/romeoandjuliet; #Nasłuchuje nowych zmian w pliku
cp
Kopiuje katalogi i pliki
cp plik1 plik2; #kopiuj plik1 na plik2 cp plik kat; #kopiuj plik1 do katalogu kat cp kat1 kat2; #kopiuj katalog kat1 do katalogu kat2 cp -a kat1 kat2; #kopiuj katalog kat1 do katalogu kat2 (z zachowaniem praw)
scp
Kopiuje pliki z komputera na komputer za pomocą protokołu ssh.
scp -r build/html lfitj.if.pw.edu.pl:/var/www/dydaktyka/bd scp -R /tmp/foo foo@bar:/tmp/baz # Kopiuje katalog /tmp/foo na server bar do katalogu /tmp/baz przy czym na zdalny serwer logujemy się na użytkownika foo
rsync
Synchronizuje dwa katalogi na dwóch komputerach oszczędzając transfer (przesyła tylko zmiany w plikach).
ssh
Pozwala na zdalne zalogowanie na inny komputer
mv
Przenosi katalogi
mv plik1 plik2; #przenieś plik1 na plik2 (zmiana nazwy pliku) mv plik kat; #przenieś plik1 do katalogu kat mv kat1 kat2; #przenieś katalog kat1 do katalogu kat2
rm
Usuwa pliki
rm plik1 plik2;# usuń plik1 i plik2 rm *~;# usuń wszystkie pliki kończące się na ~ w bieżącym katalogu rm -r kat; #usuń katalog kat wraz z podkatalogami rm -rf kat; #usuń katalog kat wraz z podkatalogami (w trybie force) rm -ri kat; #usuń katalog kat wraz z podkatalogami (w trybie interaktywnym)
less
Odczytuje plik strona po stronie
less /usr/share/romeoandjuliet;
file
Zgaduje typ pliki za pomocą magicznych numerów, czyli specjalnych ciągów bajtów znajdującyh się w pliku, które pozwalają określić rodzaj jego zawartości. Na przykład pliki, które rozpoczynają się od dwóch bajtów: 035 i 033, są plikami skryptów (jest tak ponieważ w kodowaniu ASCII1 ciąg #! ma taką reprezentację. Ciąg ten stanowi początek :ref:shebang-line.
jb@gautama:/tmp$ file Dredmor-amd64 Dredmor-amd64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, not stripped jb@gautama:/tmp$ file foo.xlsx foo: Microsoft Excel 2007+ jb@gautama:/tmp$ file cyclotron.jar cyclotron.jar: Zip archive data, at least v2.0 to extract
find
Wyszukuje pliki.
find -name "*odt"; # Uwaga " są konieczne!
grep
Wyszukuje linie w pliku
grep Romeo /usr/share/romeoandjuliet # Wyszukuje linie zawierające słowo "Romeo"
whereis
Znajduje położenie pliku o ile jest on w $PATH
whereis java; #Znajdzie położenie programu java
nano
Konsolowy edytor tekstowy
nano /etc/X11/xorg.conf;
traceroute
Pokazuje ścieżkę do zdalnego serwera
traceroute google.pl
ping
Bada czas odpowiedzi do danego hosta. Przydatne do sprawdzania istnienia i jakości połączenia internetowego.
ping google.pl
chown
Zmienia właśniciela i grupy pliku
chown foo:bar baz; # Zmienia właściciela baz na foo a grupy na bar chown -R baz ; # j.w. tylko zmienia właściciela wszystkich podkatalogów baz
chmod
Zmienia uprawnienia pliku i katalogu
chmod og-rxw foo ; #Odbiera wszystkie uprawnienia do foo wszystkim poza właścicielem chmod 700 foo ; #j.w. chmod -R 700 /tmp/foo ; #j.w. tylko zmienia uprawnienia w podkatalogach i plikach
pwd
Wyświetla bieżący katalog
pwd
ps
Listuje procesy
ps; #pokaż moje procesy, widok podstawowy ps -u user; #pokaż procesy użytkownika, widok podstawowy ps -aux;# pokaż wszystkie procesy, widok rozszerzony
top
Listuje procesy (interaktywne)
top
kill
Wysyła sygnał do procesu, za pomocą numeru procesu
kill 1111# Prosi proces o wyłączenie się kill -9 1111# Zabija proces kill -22 1111 #Zatrzymuje proces (może być potem wznowiony)
pkill
Wysyła sygnał do procesu, wyszukując procesy po nazwie
pkill firefox; #Zabija wszystkie procesy o nazwie firefox pkill -9 firefox; pkill -f netbeans; #Zabija procesy w których poleceniu pojawia się słowo netbeans
xkill
Pozwala usunąć program po kliknięciu na nim
xkill
wget
Pobiera plik za pomocą protokołu HTTP
wget google.pl
Do instalacji powłoki Bash na Winowsie można wykorzystać projekt Cygwin:, jest to projekt udostępniający środowisko POSIX-owe (POSIX to standard definiujący Linuxa) na systemach MS Windows.
Praca domowa Tematy prac domowych.