===== Procesy i zadania =====
==== Przygotuj się do laboratorium ====
* ''man textutils'' (jeżeli nie jest dostępne w systemie, spróbuj [[http://manpages.ubuntu.com/manpages/precise/pl/man1/textutils.1.html|tutaj]])
* interesują nas: **head/tail**, **cat/tac**, **wc**, **cut**, **sort**, **tr**, **uniq**, **seq**, **xargs**, **expr**
* ''man grep'' i/lub [[https://linux.fandom.com/pl/wiki/Grep|grep w Linux Wiki]]
==== Wiedza ====
=== 1. Zadania ===
Zadania (ang. //jobs//) to programy uruchamiane w sesji przez powłokę.
* usypianie (ang. //suspend)// zadań C-z ,
* spis zadań **jobs**,
* przełączanie zadań **fg**,
* praca w tle **bg**,
* usuwanie zadań **kill**,
* równoległe uruchamianie zadań (ampersand, czyli ''&''),
Powyższe polecenia są wbudowane w shell i są opisane w manualu shella!
=== 2. Procesy ===
* identyfikator PID i jego znaczenie
* wyświetlanie listy procesów **ps**, ''ps -A'' (Sun), ''ps -ax'' (Linux), a także ''ps -u user'', ''ps aux|grep user''
* zmniejszanie priorytetu **nice**,
* usuwanie procesów **kill**, ''kill -9''
=== 3. Procesy a Zadania ===
* każde uruchomienie programu w Unixie tworzy //proces//
* zadania, są mechanizmem dostarczanym przez shell dla ułatwienia obsługi uruchamianych z danej sesji (instancji shella) procesów
* żeby wyświetlić PID procesów którym odpowiadają zadania należy po uruchomieniu kilku zadań napisać ''jobs -l''
* każda sesja jest obsługiwana przez plik urządzenia //pseudoterminala//
* aby wyświetlić w.w. plik należy wpisać ''tty''
* aby wyświetlić procesy pracujące w danej sesji należy wpisać ''ps -t`tty`''
=== 4. Narzędzia operujące na tekście ===
* GNU Coreutils - zestaw podstawowych narzędzi GNU
* Interesują nas: **head/tail**, **cat/tac**, **wc**, **cut**, **sort**, **tr**, **uniq**, **seq**, **xargs**, **expr**
* Ważny jest też: **sed** (na tym etapie jest dla zaawansowanych; przejdziemy do niego na dalszych zajęciach)
* Każde polecenie ma swojego manuala. Warto też przejrzeć: ''man textutils'' (większość w.w. poleceń była kiedyś w pakiecie //GNU textutils//; jeżeli ten manual nie jest dostępny w systemie, spróbuj [[http://manpages.ubuntu.com/manpages/precise/pl/man1/textutils.1.html|tutaj]])
* **grep** służy do wyszukiwania zadanych wyrażeniami regularnymi wzorców w tekście: grep napis [plik]
Przydatne opcje:
* ''-i'' ignoruje wielkość znaków
* ''-v'' odwraca działanie **grep** (czyli wyświetl wszystkie linie, które NIE zawierają napisu)
* Dla chętnych - ciekawy artykuł od IBM: //[[https://developer.ibm.com/articles/au-unixtext/|Introduction to text manipulation on UNIX-based systems]]//
=== 5. Strumienie ===
Każdy proces pracujący w środowisku Unix komunikuje się z otoczeniem m.in. przez strumienie. Domyślnie są otwierane 3:
* 0 -- //standard input// (stdin)
* 1 -- //standard output// (stdout)
* 2 -- //standard error output// (stderr)
Powłoka pozwala na przekierowanie strumieni, w sh znakami:
[proces] > [plik] # przekierowanie stdout do pliku (NADpisanie)
[proces] 2> [plik] # przekierowanie strumienia 2 (stderr) do pliku (NADpisanie)
[proces] >> [plik] # przekierowanie stdout do pliku (DOpisanie)
[proces] < [plik] # przekierowanie stdin z pliku
# Przykłady:
ps > foo
w 2> bar
ls > foo 2> bar
Przydatny przy przekierowaniu stderr (2) jest ''/dev/null''. Pozwala na pozbycie się danych.
=== 6. Komunikacja między procesami ===
Powłoka pozwala na realizowanie komunikacji między procesami przez łączenie strumieni, uruchamiane przez znak ''|'' (ang. //pipe//). \\
Powoduje on połącznie stdout zadania 1 z stdin zadania 2. Przykłady:
ls | wc
ps | sort
# Bardziej złożone filtry:
ps aux | grep bash | wc
cut -d ':' -f 5 /etc/passwd | grep -i daemon | wc -l
Przypomnienie z poprzednich zajęć - podstawianie wyników poleceń w linii poleceń jest realizowane przez odwrotny apostrof (''`''), na przykład:
echo "To jest system" `uname` "na maszynie " `hostname`
# Wyświetli: To jest system Linux na maszynie spk-ssh
=== 7. Sygnał HUP i polecenie nohup ===
Przy zamykaniu powłoki do wszystkich procesów z niej uruchomionych wysyłany jest sygnał //HangUp// (''HUP''). \\
Aby pozostawić jakieś polecenie pracujące w tle po zamknięciu shella, należy je uruchomić za pomocą **nohup**: nohup polecenie
==== Ćwiczenia ====
=== I. Zadania ===
Ćwiczenie wykonywać w GNU Bash.
- uruchomić ''lynx www.uj.edu.pl''
- nacisnąć C-z,
- uruchomić ''lynx www.agh.edu.pl''
- nacisnąć C-z,
- napisać ''jobs'',
- uruchomić ''lynx www.pk.edu.pl''
- nacisnąć C-z,
- napisać ''jobs'',
- napisać ''fg %2'',
- nacisnąć C-z,
- itd....
- napisać ''kill %3''
- napisać ''jobs'',
- itd....
Jeżeli zadanie nie znika po ''kill'', należy użyć opcji ''-9''.
Podobne ćwiczenie powtórzyć dla innych programów, np. **less**, **mc**, itp.
=== II. Procesy ===
- Otworzyć 3 sesje (zalogować się 3 razy, np. przez SSH)
- Sprawdzić przy pomocy **ps** pracujące procesy:
* w tej samej sesji,
* tylko swoje procesy,
* wszystkie procesy w systemie,
- Przetestować działanie znanych opcji **ps**.
- Przy pomocy **kill** usunąć z sesji B procesy pracujące w sesji A.
- Jak usunąć login shell?
- Oglądnąć przy pomocy ''kill -l'' spis wszystkich sygnałów.
- Uruchomić procesy z podwyższoną wartością //nice//.
- Zmienić wartość //nice// pracującego już procesu.
- Jak wyświetlić wartość //nice// procesu?
=== III. Przekazywanie wyników pracy do plików ===
- Przekierować wyniki pracy różnych poleceń do plików, np. dla **ps ls finger who**. Przeglądnąć powstałe pliki.
- Porównać działanie ''>'' i ''>''''>'' Na przykład:
ps
ps > plik1
more plik1
ls > plik2
more plik2
ps >> plik2
more plik2
- Przekierować wyjście błędów, np:
kill 1
kill 1 1>a 2>b
* Uwaga! Przekierowania są inicjalizowane przez shell //przed// uruchomieniem polecenia! \\ Dlatego też, jeżeli mamy plik do posortowania, np: who > plik
i wykonamy: sort plik > plik
otrzymamy //pusty// plik, gdyż jego zawartość zostanie skrócona do zera //przed// posortowaniem. \\ A uruchamiając: sort plik >> plik
otrzymamy w ''plik''u posortowaną zawartość //dopisaną// do oryginalnej, nie posortowanej!
=== IV. Narzędzia operujące na tekście ====
- Mając spis zalogowanych użytkowników: who > spis
- Posortować go alfabetycznie: sort spis > spis.alf
- Wyświetlić początek i koniec spisu (Ile linii jest wyświetlanych? Jak zadać tę liczbę?):
head spis.alf
head spis.alf > spis.alf.pocz
tail spis.alf
tail spis.alf > spis.alf.kon
- Wybrać z tego spisu (przy pomocy **grep**) użytkowników, których login zawiera literę k
- Przećwiczyć inne polecenia z TextUtils.
- Powtórzyć ćwiczenia dla innych danych wejściowych, np. spisu plików, procesów, itp.
- Skąd są czytane dane jeżeli nie poda się nazwy plików w poleceniach typu **grep**, **tail**?
- Co to jest znak końca pliku i jak się go wysyła "ręcznie"?
* Po laboratorium uzupełnić wiadomości nt. wyrażeń regularnych (//grep(1)//).
=== V. Komunikacja między procesami ===
Należy ponownie wykonać ćwiczenia 1-4 z sekcji IV bez użycia plików pośrednich, tylko odpowiednio łączyć //stdin// z //stdout//, np. who | sort | grep 'k' | head
Inne przykłady:
ls | wc
ps | sort
ps -A | grep tcsh
ps | head -n 1
who | wc
who | sort
nice du -sk /usr/local/* 2> /dev/null | sort -rn | head
who | awk '{print $1;}' | sort | uniq
Proszę przeprowadzić jak najwięcej własnych eksperymentów z wykorzystaniem wszystkich znanych poleceń!
=== VI. Zadanie dodatkowe ===
Używając wyłącznie poleceń **grep, cut, tr, head, tail**, na podstawie strony [[https://nbp.pl/statystyka-i-sprawozdawczosc/kursy/tabela-a/]] stworzyć filtr generujący tekstową tabelę kursów walut. \\
Przykładowy wynik końcowy może wyglądać następująco:
bat (Tajlandia) 1 THB 0,1251
dolar amerykański 1 USD 3,8746
dolar australijski 1 AUD 2,9716
dolar Hongkongu 1 HKD 0,4988
dolar kanadyjski 1 CAD 3,0793
dolar nowozelandzki 1 NZD 2,7296
dolar singapurski 1 SGD 2,8851
euro 1 EUR 4,6073
forint (Węgry) 100 HUF 1,2557
frank szwajcarski 1 CHF 4,1704
funt szterling 1 GBP 5,3375
hrywna (Ukraina) 1 UAH 0,1398
jen (Japonia) 100 JPY 3,5653
korona czeska 1 CZK 0,1759
korona duńska 1 DKK 0,6196
korona islandzka 100 ISK 3,0963
korona norweska 1 NOK 0,4520
korona szwedzka 1 SEK 0,4524
kuna (Chorwacja) 1 HRK 0,6083
lej rumuński 1 RON 0,9423
lew (Bułgaria) 1 BGN 2,3557
lira turecka 1 TRY 0,4882
nowy izraelski szekel 1 ILS 1,1747
peso chilijskie 100 CLP 0,5405
peso filipińskie 1 PHP 0,0796
peso meksykańskie 1 MXN 0,1862
rand (Republika Południowej Afryki) 1 ZAR 0,2596
real (Brazylia) 1 BRL 0,7036
ringgit (Malezja) 1 MYR 0,9399
rubel rosyjski 1 RUB 0,0509
rupia indonezyjska 10000 IDR 2,6916
rupia indyjska 100 INR 5,3464
won południowokoreański 100 KRW 0,3427
yuan renminbi (Chiny) 1 CNY 0,5948
SDR (MFW) 1 XDR 5,5207
Uwaga! Od 2023 roku strona NBP została przebudowana i aktualnie zawiera zabezpieczenia przeciw pobieraniu zawartości przez boty. Nie ma prostego shellowego sposobu aby pobrać jej zawartość (nie zadziała ani ''curl'' ani ''ncat'' ani inne narzędzia shellowe). Dlatego stronę należy otworzyć w przeglądarce, zapisać jej kod HTML na dysku a następnie rozpocząć filtr od ''cat tabela-a.html''