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ě.
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.
ls -l -a
, rmdir
, rm -r
, echo
, mv
, mkdir -p
, man
, more
~
znamená domovský adresář (home).more název-souboru
.echo nějaký text > název-souboru
Proč to funguje je pro nás ale zatím záhada.ls -dR
, echo -ne
, rm -f
...
less
(/, n, q), cat
, cp -r
, pwd
, whoami
, who
, ...
cat
)
fg
a bg
)
/etc/passwd
ls -l -a
, ls -a -l
, ls -la
, ls -l a
?
/etc
/mnt/Win/Documents and Settings/Jenda/Plocha/Nový.txt
adam
, beda
, cyril
. Poté přejmenujte cyril
na cecil
a pak všechny tři jedním příkazem smažte
last
.
MM/DD/YYYY
a převede je do formátu DD. MM. YYYY
.
Domácí úkol:
Hello, world
Hello, world!
(se dvěma mezerami -- opravdu to umíme?)
test
(ve svém domovském adresáři)
test
/etc/fstab
mkdir -p
-- vytvoření celé cesty (např. mkdir -p skola/mff/unix/cviceni02/
)
HISTSIZE
(více hledejte v man bash
-- viz první příklad)
fg
a bg
)
/
(další výskyt klávesou n
).
ls -d
-- výpis adresáře samotného (a nikoli jeho obsahu)
ls -i
-- vypíše navíc číslo inode každého souboru
ls -R
-- rekurzivní výpis (pokud chcete výstup zpracovávat strojově, použijete asi častěji příkaz find
, který probereme někdy později)
echo -n
-- po vypsání neodřádkuj
echo -e
-- povolení escape sekvencí (například \n
-- newline; \r
skok na začátek řádky, další viz man echo
)
man -k <hledaný řetězec>
-- hledání ve všech manuálových stránkách
less
(/, n, q) -- obdoba more
-- stránkování dlouhého výstupu na obrazovku (less
se často umí i vracet v historii)
pwd
-- zjištění aktuálního pracovního adresáře
whoami
-- kdo jsem?
who
-- kdo je přihlášený
date
-- aktuální čás a datum, umí datum formátovat
ps
-- seznam procesů
last
-- seznam naposledy přihlášených uživatelů
tac
-- přehození pořadí řádku (Pozor, není součástí POSIXu!)
rev
-- přehození pořadí znaků na řádku (Pozor, není součástí POSIXu!)
tr
-- nahrazení znaků za jiné (vyzkoušejte si třeba zavolat příkaz: tr ahoj bagr
)
head -n 42
-- vypíše prvních 42 řádek std. vstupu.
tail -n 42
-- vypíše posledních 42 řádek std. vstupu.
cut
-- vyseknutí sloupečkupaste
-- slepení sloupečkůwc
-- word count -- počet řádků, slov, znaků na std. vstupusort
-- lexikografické seřazení řádků (s přepínači řadí i jinak)uniq
-- vyřazení duplicit v setřízeném vstupu/
-- kořen (root) souborového stromu
~
-- domovský adresář aktuálního uživatele (syntaktická zkratka třeba za /home/had
)
.
-- aktuální pracovní adresář
..
-- nadřazený adresář
.cokoli
-- skrytý soubor
Tyto speciální znaky interpretuje shell a nahradí je ještě před spuštěním příkazu.
~
-- domovský adresář aktuálního uživatele (nahradí se například za /home/had)
*
-- nahradí se za všechny (neskryté) soubory v aktuálním adresáři
*/*
-- funguje i rekurzivně
/*
-- použitelné i na absolutní cesty
.*
-- expanze i na skryté soubory
cat < soubor
-- přesměrování vstupu ze souboru
echo ahoj > soubor
-- přesměrování výstupu do souboru
echo ahoj >> soubor
-- append do souboru
echo ahoj 2> soubor
-- přesměrování chybového výstupu do souboru
echo ahoj | cat
-- roura (pipe) napojení výstupu z echo
na vstup cat
HISTSIZE
.
DD. MM. YYYY
a zapište je do souboru datum.
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.
dir
obsah aktuálního adresáře. Je v tomto seznamu soubor dir
? Vysvětlete proč.
echo Ahoj > soubor_1 > soubor_2 soubor_3
? A proč?
echo
vyrobte soubor s více řádky. Udělejte to dvěma (nebo i více) způsoby.
a
vytvořte soubor b
tak, aby se b
skládal z prvních 11 a posledních 4 řádků souboru a
.
nano
, nebo vim
) -- zkuste si napsat svůj první skript, který vyřeší nějaký jiný z těchto příkladů.
/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.
wget https://kam.mff.cuni.cz/~had/vyuka/1718/unix/passwd
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ě.)
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:
vim
, zkuste si projít vimtutor
.ls *
a ls
?
echo ~
?
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.
jmeno=Jenda
-- přiřadí do proměnné (pozor na mezery!)
echo $jmeno
-- vypíše proměnnou. Podobně jako u expanze *
se o proměnné stará shell. Pozor na to, že se to provádí před rozsekáním příkazu na jednotlivé argumenty.
$PATH
-- seznam adresářů, ve kterých shell hledá volané programy. Na pořadí záleží!
$HOME
-- váš domovský adresář
$USER
-- uzivatelské jméno
$PWD
-- aktuální pracovní adresář
$PS1
-- formát promptu (můžete si třeba příkazovou řádku obarvit http://www.abclinuxu.cz/clanky/bash-prompt)
$RANDOM
-- náhodné číslo (16 bitů, tj. 0 - 32767) (Pozor! tohle je specifické pro bash)
$LANG
-- nastavení jazyka, kterým k vám programy promlouvají.
Pozor, u proměnných již záleží na tom, zda použijete uvozovky "$promenna"
, nebo apostrofy'$promenna'
.
$$
-- process id (PID) aktuálně běžícího procesu$N
-- N-tý parametr skriptu (případně funkce, až si ukážeme funkce)$0
-- jméno běžícího skriptu.$#
-- počet argumentů skriptu (či funkce)$?
-- návratová hodnota posledního příkazu$@
-- všechny agrumenty skriptu, při použití "$@"
se expanduje na stejný počet argumentů, s jakým byl původní skript zavolán$*
-- všechny agrumenty skriptu, při použití "$*"
se expanduje vždy pouze na jeden argument
ls -l
, příklad: drwxr-xr-x
, -rw-r--r--
d
adresář (directory) -
obyčejný soubor.
rwx
, r
-- čtení, w
-- zápis, x
-- spouštění (u adresářů listování) (Pomlčka znamená, že na danou věc nemáme právo.)
/tmp
.
chmod
chown
(na tohle nejspíš nebudete mít právo)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.
#!/bin/sh
a přidáte mu práva na spuštění, můžete jej pouštět rovnou kratším zápisem ./muj_skript.sh
.#!/bin/bash
. Chcete-li o tomto zápise vědět víc, podívejte se na anglickou Wikipedii.$PATH
, můžete jej pak spouštět odkudkoli (tentokrát se už nepíše ./
).Sice jsme si ukázali, jak vytvářet textové soubory, ale zatím to nebylo moc pohodlné. Máme něolik možností:
cat > nazev_souboru
a následně píšeme text. Zakončíme pomocí CTRL + D.vim nazev_souboru
a naučíme se s ním:
i
-- přepne do insert módu a můžete pak normálně psát tak, jak jste zvyklíEsc
-- vyskočí z insert módu:q
-- vypne vim:w
-- uloží soubor:wq
-- lze i kombinovat: uloží a následně vypneCtrl + Q
-- rozmrazí obrazovku v případě, že jste si ji předtím zamrazili pomocí CTRL + S
vimtutor
a aspoň hodinu neděláme nic jiného. (Toto si raději nechte až na doma).nano nazev_souboru
(někdy místo něj najdete pico
)
^
znamená CTRL, takže:Ctrl + X
-- ukončeníCtrl + O
-- uložení souborukate
-- pro KDEgedit
-- pro Gnomepluma
-- pro Mate|
umí shell předávat data z jednoho příkazu do druhého ještě jedním způsobem: substitucí. Nejlépe se to ukáže na příkladu:echo "ahoj, dnes je `date` a prave probiha 3. cviceni z UNIXu"
pracovni_adresar="$(pwd)"
.cut
-- vyseknutí sloupečkupaste
-- slepení sloupečkůwc
-- word count -- počet řádků, slov, znaků na std. vstupusort
-- lexikografické seřazení řádků (s přepínači řadí i jinak)uniq
-- vyřazení duplicit v setřízeném vstupujoin
) -- slepení sloupečků podle společného klíče, necháme si na příštěgetent passwd
-- NePOSIXová specialita labu -- vypíše i síťové uživatele, obdobně jako by to udělalo cat /etc/passwd
/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:
UID:domovský adresář:uživatelské jméno
Krasny den uzivateli vaše uživateslské jméno! Vedel jsi, ze je X hodin a Y minut?
"$@"
a "$*"
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ů).Pozor, pravděpodobně si nevystačíte s dosud probranou látkou
$RANDOM
.
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ř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ů:
test "$a" = "$b"
-- splněno, pokud jsou řetězce stejnétest "$a" -lt "$b"
-- splněno, pokud je číslo v přoměnné a
menší než v b
test "$a" -eq "$b"
-- splněno, pokud jsou číslá v přoměnné a
a b
stejná[ "$a" -gt "$b" ]
-- alternativní zápis, ve skutečnosti voláte příkaz, který se jmenuje [
(což je jen jiný název pro test
)[ -d /tmp ]
-- splněno, pokud existuje adresář /tmp
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.
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 :)"
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.
a="`expr "$a" + 1`"
-- zvětšíme hodnotu proměnné a
o jednaxor="`expr "$a" != "$b"`"
-- uloží do proměnné xor jedničku právě tehdy, kdy se proměnné a
a b
liší (pro binární proměnné tedy spočte operaci xorexpr "$a" "<" 1
-- vypíše 1, pokud je a menší než 1; jinak vypíše 0Na 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.
n
řádek a následně tyto řádky ze souboru smaže. Název souboru i parametr n
dostane jako argumenty.
$RANDOM
.
read promenna
. (Pozor, stejně jako u přiřazení se zde nepíše dolar před jménem proměnné -- dává to smysl, jinak by došlo k expanzi proměnné ještě před zavoláním příkazu read
.)paste
víceřádkový soubor s nějakým prázdným.$1
, $2
, ...) je potřeba před ně psát dolar.#
. Za komentář se počítá vše od tohoto znaku do konce řádky.~/.bashrc
-- do tohoto souboru si můžete přidat vlastní nastavení vašeho bashe. Například si můžete obarvit příkazovou řádku, upravit proměnnou "$PATH"
, aby se vám dobře spouštěly vlastní programy, ...~/.bash_aliases
-- soubor, který je většinou načítaný z ~/.bashrc
. Zpravidla obsahuje vaše aliasy. Příklad:
alias feh='feh -F -Z -Y' alias mc='mc -S darkfar' alias gst='git status' alias ncal='ncal -M' alias gcal='gcal -s Mon' alias l='ls -l' alias ll='ls -Al
~/.profile
-- obdobné využití jako ~/.bashrc
. Je načítaný i ostatními shelly a ne pouze bashem. (Tipycky je bashrc načítaný právě z tohoto souboru.)./jmeno-skriptu.sh
lze ještě použít . jmeno-skriptu.sh
v takovém případě se nebude skript spouštěť v rámci nového procesu, ale v již běžícím shellu. Výhoda je, že vám zůstane obsah proměnných. Nevýhoda, že pokud se uvnitř takto includovaného skriptu zavolá exit, skončí celý váš shell.for i in "Petr Bezruc" "Medvidek Pu" David Copperfield; do echo "$i" done
for i in `seq 5`; do echo "$i" done
for i in *.jpg; do echo "$i" done
while [ $# -gt 0 ]; do case "$1" in -h|--help) echo "Toto je nápověda" exit 0 ;; -i) shift if [ $# -gt 0 ]; then vstup="$1" else echo "přepínač -i vyžaduje parametr" exit 1 fi shift ;; *) echo "Neznámý parametr $1" break ;; esac done
getopts
, který vám pomůže zpracovávat i zkrácené varianty přepínačů (např. -lra
).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
grep
-- filtrování řádků podle regulárních výrazů. Užitečné přepínače: -v -f soubor-se-vzory -n -c
egrep
-- to samé jako grep -E
seq
-- vypíše posloupnost čísel, (volitelně i s počátkem krokem).sort
-- setřídí. Užitečné přepínače: -u -n -r -t -k 3,4
tr -d
-- znaky zmaže, -c
doplněk k matchované třídě znaků, kategorie znakůcut -b
-- sekání sloupečků po bytechtac
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.
wget https://kam.mff.cuni.cz/~had/vyuka/1718/unix/polednice.txt
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
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)
wget https://kam.mff.cuni.cz/~had/vyuka/1718/unix/devatero_pohadek
tac
rev
Zde se budou průběžně objevovat případné skripty či vstupy a výstupu, které napíšeme na projektoru.
grep -E
) a ideálně neodpovídá ničemu jinému (ne vždy to půjde).
.sh
d. m. yyyy
Třebechovice pod Orebem
, Lipník nad Bečvou
.sed -r
zahoďte vše, co odpovídá danému regexu.d. m. yyyy
do formátu YYYY-MM-DD
.
sed
u. (Prohazování jmen, příjmení ID a IP adresy)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.
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 $!
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
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.)
$?
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
#!/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.
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/
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.
K
. Vyvoláte tím manuálovou stránku toho příkazu, který je zrovna napsaný na místě pod kurzorem. Pokud chcete vyvolat stránku zjiné kategorie, můžete nejprve zmáčknou číslo této kategorie a poté K
.^v
(ctrl + malé v) začnete označovat text v 2D bloku. Pokud jste například na začátku řádky, můžete začít takto označovat první znaky na několik řádcích za sebou. Poté pomocí I
(velké I) začnete psát před danou pozici (například napíšete znak #
a pomocí Escape
vyskočíte zpět do normal mode. Tím se daný znak napíše před všechny označené řádky. A vy jste tak zakomentovali celý blok kódu. Obdobně můžete kód i odkomentovat: označíte všechny potřebné znaky #
a stiskem klávesy d
vše smažete..
-- když zmáčkente tečku, provede se poslední příkaz znovu. Pokud byste jako poslední příkaz měli například I#Escape
-- vložení znaku #
na začátek aktuální řádky, můžete poté stiskem klávesy tečka zakomentovávat libovolnou jinou řádku, na kterou se posunete.~/.vimrc
-- nastavení: pokud si ve svém home vytvoříte soubor .vimrc
, můžete do něj napsat nějaké nastavení, které si vim vždy načte při editaci souborů. Například doporučuji následující:
set number
-- zapne číslování řádků -- nalevo se vám zobrazí čislování.set scrolloff=5
-- delších skriptů se vám vždy zobrazuje v terminálu jen nějaké malé okolí aktuálně editované řádky. (Víc se toho na obrazovku zkrátka nevejde.) Tento výřez se defaultně pohybuje až ve chvíli, kdybyste s kurzorem vyjeli mimo výřez. Pomocí tohoto nastavení se vám výřez bude posouvat už o 5 řádek dřív, takže další řádky uvidíte dřív, než na ně opravdu dojede kurozr.syntax on
-- zapne obarvování syntace podle automaticky detekovaného typu souboru.set wildmenu
-- pro dvojtečkové příkazy funguje ve vimu doplňování tabulátorem. Zapnutím wildmenu se vám začne ukazovat řádek s možnostmi, které máte: zkuste si například napsat :e Tabulátor
.set ignorecase
-- při vyhledávání se bude ignorovat velikost velkých a malých písmen.set hlsearch
-- podbarví všechy výskyty hledaného řetězce.set incsearch
-- pokud budete něco hledat pomocí /
, bude docházet k vyhledávání průběžně, jak píšete hledaný řetězec.set list listchars=trail:-,tab:<.,extends:>,precedes:<,nbsp:~
-- Zapne zvýrazňování bílých znaků. Uvidíte pak rozdíl mezi mezerou, tabulátorem a nedělitelnou mezerou. Dokonce se vám začnou pomocí pomlčky zvýrazňovat i mezery na koncích řádků, které by jinak nebyly vidět vůbec.set smartindent cindent autoindent
. Vnořené bloky se vám pak budou odsazovat samy a vy se skoro nemusíte starat o to, aby byl kód dobře čitelný. Při prasní shellových skriptů to sice nepomůže tolik jako u C, ale něco to také zvládne.mc
. Pokud jste někdy viděli něco jako
Norton commander, Volkov Commander, nebo Total Commander, může vám být
trochu povědomý.M-?
, tedy Meta + otazník.apt install
termux-api
. Od této chvíle máte příkaz
termux-cliboard-set
. Když na standardní vstup tohoto
příkazu něco pošlete, objeví se to v kopírovací schránce a můžete to
ihned vložit v porhlížeči do odevzdávacího systému.termux-clipboard-get > soubor
.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.