Cvičení z Úvodu do UNIXu


V letním semestru 2017/2018 vedu cvičení předmětu Úvod do UNIXu [NSWI095]. Cvičení probíhají v úterý od 14.00 v učebně SU2, hned po přednášce. Primárně se budeme držet právě úterní (české) přednášky Libora Forsta (viz stránky přednášky).

Pokud nebudete nic namítat, tak si budeme tykat ;-)

Stručně: 50% bodů z domácích úkolů + zápočtová písemka na jednom z posledních cvičení + buďte aktivní na hodině.

Co se událo? / Co máme v plánu?

První seznámení s příkazovým řádkem, procházení historie, pár základních příkazů, ukázka odevzdávacího systému.

Obsah

Úvod

Když se pokazí grafické rozhraní...

Základy v terminálu

Užitečné, ale zatím neprobrané

Příklady

  1. Zobrazte manuálovou stránku k souboru /etc/passwd
  2. Jaký je rozdíl mezi ls -l -a, ls -a -l, ls -la, ls -l a?
  3. Vypište obsah /etc
  4. Smažte soubor /mnt/Win/Documents and Settings/Jenda/Plocha/Nový.txt
  5. Vytvořte složku lide a v ní tři složky adam, beda, cyril. Poté přejmenujte cyril na cecil a pak všechny tři jedním příkazem smažte

Příklady pro šílence

  1. Vypište jména všech uživatelů, kteří se někdy přihlásili na váš počítač, každého právě jednou. Seznam přihlášení získáte příkazem last.
  2. Napište skript, který provede množinový průnik. Na vstupu dostane dva soubory a má vypsat právě ty řádky, které se vyskytují v obou souborech. Na pořadí nezáleží.
  3. Napište skript, který provede množinový rozdíl. Na vstupu dostane dva soubory a má vypsat právě ty řádky, které se vyskytují v prvním a nevyskytují ve druhém. Na pořadí záleží (musí být stejné jako v prvním souboru).
  4. Napište skript, který vyhledá všechna data v souboru zapsaná ve formátu MM/DD/YYYY a převede je do formátu DD. MM. YYYY.
  5. Vypište posledních 10 přihlášených uživatelů na vašem počítači, v pořadí dle času jejich posledního přihlášení.

Domácí úkol:

Obsah

Opakování z minula -- co byste měli umět

  1. Vypište: Hello, world
  2. Vypište: Hello,  world! (se dvěma mezerami -- opravdu to umíme?)
  3. Vytvořte adresář test (ve svém domovském adresáři)
  4. Smažte adresář test
  5. Přečtěte obsah souboru /etc/fstab
  6. mkdir -p -- vytvoření celé cesty (např. mkdir -p skola/mff/unix/cviceni02/)

Základy v terminálu -- co jsem dříve neprozradil

Nové přepínače

Nové příkazy

Nové příkazy, avšak neprobrané pořádně

Zajímavé soubory:

Speciální znaky a expanze

Tyto speciální znaky interpretuje shell a nahradí je ještě před spuštěním příkazu.

Přesměrování a roura

Příklady

  1. Najděte v manuálu bashe informace o HISTSIZE.
  2. Vypište aktuální datum ve formátu DD. MM. YYYY a zapište je do souboru datum.
  3. Napište skript, který vyhledá všechna data v souboru zapsaná ve formátu DD. MM. YYYY a převede je do formátu DD/MM/YYYY. Můžete předpokládat, že nic jiného se v souboru nevyskytuje.
  4. Vypište do souboru dir obsah aktuálního adresáře. Je v tomto seznamu soubor dir? Vysvětlete proč.
  5. Co udělá příkaz echo Ahoj > soubor_1 > soubor_2 soubor_3? A proč?
  6. Pomocí echo vyrobte soubor s více řádky. Udělejte to dvěma (nebo i více) způsoby.
  7. Z textového souboru a vytvořte soubor b tak, aby se b skládal z prvních 11 a posledních 4 řádků souboru a.
  8. Zkuste si práci s nějakým textovým editorem (např. nano, nebo vim) -- zkuste si napsat svůj první skript, který vyřeší nějaký jiný z těchto příkladů.
  9. Ze souboru /etc/passwd vytáhněte seznam ve formátu uživatelské jméno:shell (každý záznam na samostatném řádku). Můžete používat dočasné soubory.
    • Pokud používáte obskurní systém (např. Android) a nemáte soubor /etc/passwd, můžete si stáhnout příklad: wget https://kam.mff.cuni.cz/~had/vyuka/1718/unix/passwd

Příklady pro pokročilé

  1. Vypište posledních 10 přihlášených uživatelů na vašem počítači, v pořadí dle času jejich posledního přihlášení. A tentokrát už opravdu nebude dělat něco jiného! :-)
  2. Stáhněte si nějakou webovou stránku a vypište z ní všechny odkazy. Může se vám hodit příkaz wget nebo curl na stahování. (Měli byste fungovat na různé stránky, které mohou mít HTML kód zalámaný odlišně.)
  3. Napište skript, který vyhledá všechna data v souboru zapsaná ve formátu MM/DD/YYYY a převede je do formátu DD. MM. YYYY. Pozor, prohazují se dny a měsíce! V souboru mohou být i jiné věci a měli byste je zachovat.

Domácí úkol:

Opakování z minula -- co byste měli umět

  1. Jaký je rozdíl mezi ls * a ls?
  2. Hledat v manuálu.
  3. Vysekat ze souboru konkrétní řádky (např. 4. až 10 řádka).
  4. Co se napíše při volání echo ~?

Proměnné

Minule jsme narazili na existenci proměnných (při náhodném výběru, kdo půjde ukázat řešení). Tentokrát si je i vysvětlíme a snad i naučíme používat.

Pozor, u proměnných již záleží na tom, zda použijete uvozovky "$promenna", nebo apostrofy'$promenna'.

Proměnné použitelné ve skriptech

Práva souborů:

Psaní skriptů

To, co píšete do terminálu si můžete uložit do souboru. Následně můžete zavolat váš shell a dát mu jako parametr váš soubor, tj. skript. Tedy například zavoláním sh muj_ukol.txt spustíte postupně všechny příkazy napsané v daném souboru.

Jak na textové soubory

Sice jsme si ukázali, jak vytvářet textové soubory, ale zatím to nebylo moc pohodlné. Máme něolik možností:

Substituce příkazů

Nové příkazy

Příklady

  1. Přečtěte soubor /etc/passwd (Pokud používáte obskurní systém -- např. Android -- a nemáte soubor /etc/passwd, můžete si stáhnout příklad: wget https://kam.mff.cuni.cz/~had/vyuka/1718/unix/passwd) a vytáhněte z něj následující informace:
    1. seznam uživatelských jmen (každé jméno na jednom řádku)
    2. seznam uživatelských id uid
    3. vytvořte soubor ve formátu: UID:domovský adresář:uživatelské jméno
    4. Spočítejte kolik různých shellů používají všichni uživatelé v labu.
  2. Napište skript, který vás pozdraví a řekne vám, kolik je hodin. Tj. vypíše například Krasny den uzivateli vaše uživateslské jméno! Vedel jsi, ze je X hodin a Y minut?
  3. Napište skript, který vypíše počet argumentů, se kterými byl zavolaný
  4. S použitím předchozího skriptu napište skript, na kterém půjde pěkně ukázat rozdíl mezi "$@" a "$*"
  5. Vypište jména uživatelů sítě (getent passwd), která se vyskytují více než jednou (buď proto, že se více osob jmenuje stejně, nebo protože má jedna osoba více loginů).
  6. Vypište jména uživatelů sítě, která se vyskytují více než jednou, VELKÝMI PÍSMENY a setřízená podle příjmení (klidně předpokládejte, že jeden člověk má jen jedno jméno a jedno přijmení).
  7. Napište skript, který si uloží do nějaké proměnné aktuální datum s co největší přesností. Pak založí nový adresář s nějakým unikátním jménem (na základě této proměnné), přepne se do něj a spustí tam skript, který dostane jako svůj argument. Po skončení vnitřního skriptu byste měli vypsat obsah tohoto dočasného adresáře a následně jej smazat (tj. uklidit po druhém skriptu).

Příklady pro pokročilé

Pozor, pravděpodobně si nevystačíte s dosud probranou látkou

  1. Napište skript, který s vámi bude hrát hádání čísel – bude si myslet náhodné číslo a vždy když zadáte svůj tip, tak vám napoví zda je menší nebo větší. Pokud se trefíte, tak vám pogratuluje a skončí. Náhodné číslo můžete získat např. z proměnné $RANDOM.
  2. Napište skript, který vypíše rekurzivně obsah aktuálního adresáře. Počítejte klidně, že skript se vyskytuje na pevné adrese (třeba ve vašem home).

Opakování z minula -- co byste měli umět

  1. Vyseknout konkrétní sloupeček z textového souboru
  2. Slepit sloupečky pomocí libovolného znaku
  3. Přiřadit do proměnné a zase z ní hodnotu přečíst
  4. Uložit do proměnné standardní výstup z nějakého příkazu
  5. Napsat jednoduchý skript

If a While

Podmínky a cykly znáte již z programování, takže je pro nás důležité hlavně to, jak se taková věc píše v shellu.

if podmiňovací příkaz; then
	...
elif podmiňovací příkaz; then
	...
else
	...
fi

while cyklus:

while podmiňovací příkaz; do
	...
done

To, která větev se vykoná, záleží na návratové hodnotě příkazu. Typicky využijete příkaz test, ale můžete použít i libovolný jiný.

Příkaz test

Předně příkaz test má velmi přehledné manuálové stránky, takže aspoň ze začátku nemá smysl se snažit naučit nazpaměť jednotlivé parametry, ale vždy si otevřít man test. Pár příkladů:

Poznámky: magické dvouznaké parametry lt, eq, le, gt, ne jsou z anglických "less than, equal, less or equal, greater than, not equal". Dávejte si pozor na mezery a proměnné nezapomeňte psát v uvozovkách.

Zkrácené vyhodnocování

Na příkazech lze provádět logické operace and a or (&& a ||). Šikovné je, že v shellu se používá zkrácené vyhodnocování. Takže pokud použijete or a první příkaz je splněný, nebude se druhý vůbec provádět. Jednoduché podmínění příkazu tak lze napsat i bez konstrukce if. Například můžeme vypsat ladící hlášku, pokud je v proměnné verbose hodnota alespoň 3:

[ "$verbose" -ge 3 ] && echo "Skript funguje :)"
[ "$verbose" -lt 3 ] || echo "Skript funguje :)"

Příkaz expr

Pokud budete chtít u zkoušky něco spočítat a budete mít zakázáno použít awk, nejspíš budete chtít sáhnout po příkazu expr. Ten umí vyhodnocovat aritmetické operace. Jediná věc, na kterou musíme dávat pozor je to, že kolem všech operací musíme psát mezery. Nemá smysl tady vyjmenovávat, co příkaz umí: manuál je opět poměrně přehledný. Nezapomeňte si dát pozor na porovnávací operace: < a >, pokud je nanpíšete do uvozovek, bude je shell chápat jako přesměrování vstupu a výstupu.

Aritmetická expanze -- u zkoušky nejspíš neprojde

Na většině dnešních shellů funguje aritmetická expanze. V zásadě nám umožňuje počítat s proměnnými mnohem příjemnějším způsobem, než expr. Dokonce jsem se asi setkal s větším množstvím systémů, kde fungovala aritmetická expanze a nebyl tam příkaz expr, než naopak. Ale i přes to, u zkoušky použití aritmetické expanze nejspíš neprojde. Pokud se ale chcete naučít shell používat kvůli sobě, používejte aritmetickou expanzi.

a=4
b="$((a + 4))"
echo "$((a*a + b*b))"
echo "$((a*(a + b)*b))"

Portože výstupem je číslo, nestane si často nic závažného, pokud uvozovky vynecháte.

Příklady

  1. Napište skript, který přečte ze souboru prvních n řádek a následně tyto řádky ze souboru smaže. Název souboru i parametr n dostane jako argumenty.
  2. Napište skript, který vypíše součet dvou čísel zadaných jako argumenty.
  3. Napište skript, který vypíše minimum ze dvou čísel zadaných jako argumenty.
  4. Napište skript, který s vámi bude hrát hádání čísel – bude si myslet náhodné číslo a vždy když zadáte svůj tip, tak vám napoví zda je menší nebo větší. Pokud se trefíte, tak vám pogratuluje a skončí. Náhodné číslo můžete získat např. z proměnné $RANDOM.
  5. Napište skript, který bude hrát druhou stranu předchozí hry. Vaším úkolem je si myslet číslo a skript bude hádat. Skript by měl hrát efektivně a snažit se půlit interval. (Když to dobře půjde, můžeme nechat oba skripty hrát proti sobě -- tentokrát jim budeme vstupy přepisovat ručně.)
  6. Napište skript, který vypíše rekurzivně obsah aktuálního adresáře. Počítejte klidně, že skript se vyskytuje na pevné adrese (třeba ve vašem home).
  7. Napište skript, který si uloží do nějaké proměnné aktuální datum s co největší přesností. Pak založí nový adresář s nějakým unikátním jménem (na základě této proměnné), přepne se do něj a spustí tam skript, který dostane jako svůj argument. Po skončení vnitřního skriptu byste měli vypsat obsah tohoto dočasného adresáře a následně jej smazat (tj. uklidit po druhém skriptu).

Dodatek ukázaný pouze na tabuli

Co jsem zapomněl ukázat dříve...

Drobnosti, které se nevešly jinam...

Nové konstrukce

Regulární výrazy

Základní regex      Rozšířený regex      význam
-------------------------------------------------------------------------
.                   .                    libovolný znak
[a-fxyz]            [a-fxyz]             jeden znak z množiny
[^a-z]              [^a-z]               jeden znak mimo množinu
*                   *                    libovolný počet opakování (i 0x)
                    +                    alespoň jedno opakování
                    ?                    nejvýše jedno opakování
\{n,\}              {n,}                 alespoň n opakování
\{n,m\}             {n,m}                alespoň n a nejvýš m opakování
\(...\)             (...)                skupina znaků
\2                  \2                   obsah 2. zapamatované skupiny
                    ab|cd|ef             jedna z alternativ
^                   ^                    začátek řetězce
$                   $                    konec řetězce

Nové příkazy

Nové přepínače

Příklady

  1. Napište náhradu příkazu tac
  2. Na vstupu dostanete matici, přidejte k ní nový poslední sloupeček obsahující součet čísel v každém řádku
  3. Vysvětlete, proč nefunguje následující:
    echo ahoj > soubor
    cat soubor | read k
    echo "$k"
    
    ale přitom funguje:
    echo ahoj > soubor
    echo nazdar >> soubor
    cat soubor | while read k; do
    	echo "$k"
    done
    

    Obecně platí, že hodnoty proměnných se předávají z rodičovského procesu do potomků, ale nikdy naopak.

    Abychom lépe vysvětlili příklad, přidáme si ještě jednu otázku. Uvažujme následující kód:

    read k
    echo "$k"
    

    Otázka: Když zavoláme program read, tak ten přece nemá možnost předat data do shellu, ze kterého je volaný. Proč to tedy funguje?

    Odpověď: read ve skutečnosti není program, ale interní příkaz shellu. Takže se nespouští žádný proces, ze kterého by bylo potřeba hodnoty proměnných dostat do rodičovského procesu.

    Otázka: Proč tedy nefunguje cat soubor | read k?

    Odpověď: Protože při použití roury | se automaticky musí spustit levá a pravá část současně. To lze zařídit jen tak, že to budou dva samostatné procesy, které se na sebe naváží. (Obecně: pokud je rour N, tak se vytvoří N+1 procesů.)

    Takže se spustí nový shell, ve kterém se zavolá interní příkaz read. Hodnoty proměnných z tohoto shellu se nemají jak dostat ven do rodičovského procesu, takže jejich obsah zmizí s uknočením procesu. (Pokud se použije přesměrování <, tak si vystačíme na provedení celého řádku s jediným procesem, takže varianta read k < soubor funguje.)

    Otázka: Proč ale funguje varianta s while-cyklem?

    Odpověď: Funguje to naprosto stejně jako předchozí případ. Vytvoří se opět dva procesy -- první bude provádět cat soubor a druhý vše, co je od roury napravo. Protože je tam ale složitější konstrukce (cyklus), tak celá pravá strana je ve skutečnosti vše od while až do done. Uvnitř tohoto procesu se již read k dokáže provádět bez vytváření dalšího podprocesu, takže se provede celý cyklus stejným shellem a hodnota proměnné je po celou dobu k dispozici.

    Z tohoto cyklu se ale nedostane ven, protože tam už tento proces nebude existovat. Takže kdybychom zavolali:

    k=10
    seq 2 | while read k; do
    	echo "$k"
    done
    echo "$k"
    

    dostaneme na výstupu:

    1
    2
    10
    

    Kde první dva řádky se vypíší cyklem a poslední (10) odpovídá hodnotě proměnné ve vnějším shellu.

  4. Najděte pět nejpoužívanějších slov v textu. Například si můžete stáhnout Polednici: wget https://kam.mff.cuni.cz/~had/vyuka/1718/unix/polednice.txt
  5. Určete, kolikrát je v souboru nějaké konkrétní slovo
  6. Přejmenujte všechny soubory v aktuálním adresáři z *.JPG na *.jpg.
  7. Vypište jména a přijmení všech uživatelů, jejichž jméno se skládá z alespoň tří slov.

Půlanketa

funkce

Abychom se vyhli opakování stejného kusu kódu, můžeme si nějaké funkční celky uzavřít do funkcí, které následně budeme volat. Funkce se také občas hodí k tomu, abychom neměli zbytečně dlouhý kus kódu. V neposlední řadě se hodi ke zkoušce, protože na papíře se špatně vkládá několik řádků.

#!/bin/sh
funkce() {
	echo ahoj!
	echo já jsem funkce "$0" a byla jsem zavolána s "$#" parametry.
	echo Například druhý parametr má hodnotu: $2.
	echo také vím, že máĺ dostat parametr v proměnné vstup. Jeho hodnota je následující: "$vstup"
	echo Protože jsem hodná, tak na výstup uložím o jedna vyšší číslo:
	vystup=$(( vstup + 1 ))
	echo
}


funkce 1 2 3

vstup=6

funkce 1 2 3

echo $vystup

sed

Příkazy sedu načítáme z řádky nebo ze souboru:

		sed 'příkazy' soubor1 soubor2 ...
		sed -f 'soubor_s_příkazy' soubor1 soubor2 ...
		sed -e 'příkazy' -f 'soubor_s_příkazy' soubor1 soubor2 ...

Důležitý přepínač je -n – nevypisovat defaultně na výstup. Další je -r zapínající extended regulární výrazy. Příkazy od sebe můžeme oddělovat středníky nebo znaky nového řádku. Syntaxe příkazů sedu je vždy následující:

		[adresa1[,adresa2]]příkaz[parametry]

Pokud není uvedena adresa, provede se příkaz pro každý řádek. Pokud je uvedena pouze adresa1, provede se příkaz pro řádek odpovídající adrese. Pokud je uvedena i adresa2, provede se příkaz pro všechny řádky mezi adresou1 a adresou2 (včetně). Adresa může být číslo řádku, $ pro poslední řádek nebo /regexp/.

Sed pracuje se dvěma prostory – pattern space (PS), do kterého se načítá každá nová řádka a hold space (HS), s jehož obsahem manipulujeme sami. Nic dalšího nemáme, žádné proměnné apod. Pouze příkazy pro manipulaci s obsahem pattern space a hold space. Seznam příkazů naleznete v manuálové stránce sedu. Nejpoužívanější jsou:

n ... vypsání současného PS (není-li -n) a načtení dalšího řádku do PS
N ... připojení dalšího řádku do PS
d ... smazání PS, začne od začátku
D ... smazání prvního řádku PS, začne od začátku, ale nenačítá vstup, je-li PS neprázdný
p ... vypíše PS na standardní výstup
P ... vypíše první řádek PS

h ... kopíruje PS do HS
H ... připoujuje PS do HS
g ... kopíruje HS do PS
G ... připojuje HS do PS
x ... prohazuje obsah PS a HS

:l ... značka l
bl ... skočí na značku l
tl ... skočí na značku l, pokud došlo od posledního načtení řádku k úspěšnému nahrazení s///
Tl ... skočí na značku l, pokud nedošlo od posledního načtení řádku k úspěšnému nahrazení s///
s/// ... nahrazení (s přepínačem g nahrazuje všechny výskyty na řádku a ne pouze první. Příklad:  s/ahoj/nazdar/g)
y/// ... transliterace (jako tr, bez rozsahů)

q ... ukončí zpracování vstupu a vypíše PS (není-li -n)

Příklady:

  1. Najděte pět nejpoužívanějších slov v textu. Například si můžete stáhnout devatero_pohadek: wget https://kam.mff.cuni.cz/~had/vyuka/1718/unix/devatero_pohadek
  2. Určete, kolikrát je v souboru nějaké konkrétní slovo
  3. Přejmenujte všechny soubory v aktuálním adresáři z *.JPG na *.jpg.
  4. Vypište jména a přijmení všech uživatelů, jejichž jméno se skládá z alespoň tří slov.
  5. Napište náhradu příkazu tac
  6. Napište náhradu příkazu rev
  7. Nahraďte všechny výskyty slova kočka slovem pes (např. v devaetru pohádek)

Zde se budou průběžně objevovat případné skripty či vstupy a výstupu, které napíšeme na projektoru.

Příklady na grep a sed:

  1. Napište regulární výraz, který odppovídá... (testujeme pomocí grep -E) a ideálně neodpovídá ničemu jinému (ne vždy to půjde).
    1. Jménu a příjmení
    2. Jménu a příjmení (povolíme i více jmen)
    3. Algebraickému výrazu (něco jako 4 + 2)
    4. Jménům souborů s příponou .sh
    5. Datu ve formátu d. m. yyyy
    6. Libovolnému HTML tagu (pro hnidopichy: budeme předstírat, že například neexistuje nic jako CDATA.
    7. Obcím, které mají název "něco nad, nebo pod něčím". Třebechovice pod Orebem, Lipník nad Bečvou.
  2. Použijte regex z příkladu 1.6 a zkuste přeformátovat nějakou HTML stránku na čistý text (třeba stránku cvičení). Jinými slovy: pomoci sed -r zahoďte vše, co odpovídá danému regexu.
  3. Převeďte datum z formátu d. m. yyyy do formátu YYYY-MM-DD.
  4. Proveďte množinový průnik dvou souborů: vypište právě ty řádky, které se vyskytují v obou souborech.
  5. Proveďte množinový rozdíl dvou souborů: vypište právě ty řádky, které se vyskytují v prvním, ale nevyskytují ve druhém.
  6. Stáhněte si webovou stránku a zkuste z ní vytěžit co nejvíc odkazů na další stránky.
  7. Napište skript, který vypíše na svůj standardní výstup shellový skript, který by v aktuálním adresáři přejmenoval všechny soubory s velkými písmeny v názvu na malá písmena a nahradil mezery za pomlčky čí podrtžítka
  8. Vyřešte 3. domácí úkol pomocí sedu. (Prohazování jmen, příjmení ID a IP adresy)
  9. Další příklady:

  10. Zkuste si funkce: vypište rekurzivně obsah aktuálního adresáře (bez použití rekurzivního ls, či find.

Zde se budou průběžně objevovat případné skripty či vstupy a výstupu, které napíšeme na projektoru.

# ODKAZY
# ------
# vytvoříme symbolický odkaz (symlink):
ln -s soubor odkaz

# Hardlink:
ln soubor odkaz

# Od této chvíle jsou soubor a odkaz k nerozlišení
# Zapíšeme-li do jednoho z nich, druhý bude také přepsán:
echo koala > soubor
cat odkaz

# JOIN
# ----
# Když jsme probírali cut a paste, tak jsme ještě vynechali příkaz join

Bude doplněno...

Zde se budou průběžně objevovat případné skripty či vstupy a výstupu, které napíšeme na projektoru.

Zde se budou průběžně objevovat případné skripty či vstupy a výstupu, které napíšeme na projektoru.

Procesy a vlákna

Aspoň na Linuxu je rozdíl mlhavý -- jednotlivá vlákna od sebe mohou být různě izolovaná a od určité míry izolace to už nazveme jako separátní proces.

Interaktivní příkazy: top, htop.

Důležité: PID, PPID, init proces (PID 1)

Pouštění příkazu na pozadí pomocí &

Příkazy fg, bg, jobs, pozastavení pomocí Ctrl+Z

Ukázali jsme si exec (Ale příliš jsme si nevysvětlili podobu s vytvořením nového procesu (fork & exec).

Ukázali jsme si wait a $!

Příklady:
  1. Napište sleep sort. Tip: na konec se hodí dopsat wait
  2. Zkuste si napsat funkci, max, která najde maximum ze svých argumentů. Tou se pak dá sleep sort rozšířit: wait na konci bude čekat jen na ten proces, který byl volaný s maximálním argumentem. Využití: takto přímo asi nulové, ale aspoň je to dobře definovaná úloha, kterou si člověk může vyzkoušet

Exitcode

Napište si vlastní funkci, která bude fungovat jako taková podmínka. Dostane jako argument soubor a uspěje, pokud se v daném souboru nevyskytuje slovo bagr. (Pokud soubor neexistuje, nebo je to adresář, podmínka neuspěje.)

$?

Signály

Procesy si navzájem mohou posílat signály (obdoba Interruptů – přeušení, viz principy počítačů).

# Údajně POSIX definuje následující (neověřoval jsem si):
1  SIGHUP    (hang up)
2  SIGINT    (interrupt)
3  SIGQUIT   (quit)
6  SIGABRT   (abort)
9  SIGKILL   (kill)
14 SIGALRM   (alarm)
15 SIGTERM   (terminate)


# Důležité podle mě:
jméno    číslo   popis
--------------------------------------------------------
SIGINT           To co pošle Ctrl+C
SIGKILL  (9)     Nelze se mu bránit, zabije proces
SIGHUP           Zavření terminálu (pro daemony načtení konfigurace)
SIGTERM          Měkké ukončení -- posílá se automaticky pří vypínání systému všem procesům, po nějakéĺ timeoutu se pošle SIGKILL
SIGTSTP          To, co posílá Ctrl+Z, zastavení procesu
SIGCONT          Rozběhnutí procesu
SIGCHLD          Tento signál obdrží proces, když doběhne nějaký jeho potomek
wait
$PID
$!

Tipické využití: kopíruji si disk pomocí dd, chci znát průběh, pošlu mu signál SIGUSR1

Chci ukončit nějaký konkrétní proces, zavolám kill "$pid". Pokud vzdoruje, pošľu mu SIGKILL: kill -9 "$pid".

Pro pokročilé: příkaz pkill

Chci-li signál odchytit v shellu, použiji trap příkaz signál

Příklady:
  1. Napište program, který vypíše jméno signálu, který mu byl zaslán (kromě SIGKILL) a běží dál bez ukončení. Stačí umět zpracovat standardní POSIXové signály. Posílejte tomuto programu různé signály pomocí kill, abyste vyzkoušeli jeho chování.
  2. Vyzkoušejte si uklízení dočasných souborů. Máme následující skript:
    #!/bin/sh
    
    zpracovavej_data () {
    	echo "Vypisuji cislo $1 do souboru $docasny_adresar/$1.temp"
    	echo "$1" > "$docasny_adresar/$1.temp"
    	sleep 1
    }
    
    docasny_adresar="`mktemp -d`"  # mktemp není v POSIXu, na zkoušce si jej možná budete muset naprkogramovat sami, ale pro reálný život je moc užitečný
    
    echo "Ahoj! Jsem skript, který si právě založil dočasný adresář $docasny_adresar"
    echo "Teď do něj jdu ukládat svá data..."
    
    seq 40 | while read number; do
    	zpracovavej_data "$number"
    done
    
    rm -rf "$docasny_adresar"
    
    Doplňte do něj pomocí trap takovou funkcionalitu, aby při předčasném zabití skriptu pomocí Ctrl+C došlo k pročištění dočasných souborů.

Zadání je na samostatné stránce.


Vzdálený přístup do labu

Jeden z důvodů, proč je dobré se naučit s příkazovou řádkou je ten, že občas potřebujeme nějaký počítač ovládat na dálku. Příkazová řádka se pak chová prakticky stejně ať už u počítače sedíte, nebo jste od něj stovky kilometrů daleko. I s dnešními rychlostmi připojení je občas přenos barevného obrazu docela náročný, ale přenést pár kilobytů textu funguje prakticky vždy.

K unixovému stroji se dnes nejčastěji přiipojeujeme pomocí programu ssh (secure shell). Chcete-li se například přípojit do labu, můžete použít příkaz ssh uživatelské-jméno-v-labu@u-pl7.ms.mff.cuni.cz. Vybrat si můžete samozřejmě i jiný počítač. Jejich senznam je na stránkách laboratoře: http://wiki.ms.mff.cuni.cz/wiki/Počítače_UNIX

Pokud chcete překopírovat nějaký soubor, použijte příkaz scp. Pokud byste například chtěli na cvičení ukázat svůj skript, nakopírujte jej do adresáře /tmp/ na počítači u-pl22.

  scp muj_skript u-pl22:/tmp/
  scp muj_skript uživatelské-jméno-v-labu@u-pl22.ms.mff.cuni.cz:/tmp/

Vim

Otázka: Víš jaký je nejlepší textový editor? Odpověď: Ano, vim.

Vim toho umí spoustu, ale ne vždy člověk ví, co se má snažit hledat. Zkusím zde přidat pár tipů, které pomohou s efektivnějším využíváním.

Midnight Commander

Termux -- terminál v androidu

Konzultace

Chcete-li něco probrat osobně, neváhejte přijít na konzultaci! Zatím nemám vypsaný žádný pravidelný termín, takže se se mnou domluvte e-mailem nebo osobně na cviku.

Kontakt