MFF Notebook > Unix > Příklady

Příklady

Modelové příklady i s jejich řešením a popisem řešení.

Vypište 20 nejčastějších jmen s jejich počtem z ypcat.
ypcat passwd | cut -f5 -d: | cut -f1,2 -d' ' | fgrep -v konto | cut -f1 -d' ' | sort | uniq -c | sort -n -r | head -20
fgrep je jako grep; jen nebere regulární výraz, ale jen posloupnost znaků
Vypište ze souboru všechna sedmiznaková slova, která začínají samohláskou a končí na ball.
grep '^[aeiouy]..ball$' /usr/dict/words
Určete počet řádek v souboru, který obsahuje rss, RSS, vsz, nebo VSZ.
egrep -i '(rss|vsz)' / tmp/ps.man | wc -l
Na základě příkazu find vypište pouze jména třech souborů z /usr/bin/ , které mají nejvyšší počet hardlinků.
find /usr/bin/ -type f -ls | sort -k4,4n | tail -3 | tr -s ' ' | cut -d' ' -f12
Vypíšte ze souboru file obsah ohraničený řádky BEGIN a END.
BEGIN=`cat -n file | grep '^BEGIN$' | cut -f1`
BEGIN=`echo "$BEGIN+1" | bc`
END=`cat -n file | grep '^END$' | cut -f1`
END=`echo "$END-1" | bc`
sed -ne "$BEGIN,$END p" file
- najde, na kterém řádku je BEGIN a k hodnotě přičte jedničku
- najde, na kterém řádku je END a od hodnoty odečte jedničku
- vrátí řádky mezi BEGIN a END pomocí sedu
V aktuálním adresáři smažte všechny soubory, jejichž název končí na text uvedený v souboru s1 (např. .jpg). Spočítejte počet neúspěšných pokusů o smazání souboru. (Předpokládejte, že nemáte alias rm='rm -i' .)
find ~ -type f -name "*`cat s1`" -exec rm -i {} 2>failed \;
cat failed | wc -l
hvězdička v příkazu find musí být v uvozovkách, jinak jí expanduje shell
Ze souboru apache.log vypište všechny různé IP adresy seřazené podle počtu požadavků GET z těchto adres.
cat apache.log | fgrep GET | cut -f6 -d" " | sort | uniq -c | sort -n -r -k1
Chyby ze souboru apache.log, tj. řádky obsahující [error], přidejte na konec souboru error.log.
grep "\[error\]" apache.log >> error.log
Do proměnné MAX uložte největší trojciferné UID (3. sloupec oddělený „:“) z výstupu ypcat passwd.
ypcat passwd | cut -f3 -d: | sort -n | tail -1
ypcat passwd je serverové /etc/passwd
Vypište 5. řádek ze souboru s1 a s2 do souboru /tmp/x-username (kde username je uživatelské jméno).
touch /tmp/x-$USER
cat s1 | head -5 | tail -1 >> /tmp/x-$USER
cat s2 | head -5 | tail -1 >> /tmp/x-$USER
V proměnné RC má být uloženo rodné číslo ve formátu nnnnnn/nnn případně nnnnnn/nnnn. Ověřte pomocí příkazu grep, že obsah proměnné RC odpovídá formátu (n=cifra).
echo $RC | grep -c '^[0-9]\{6\}/[0-9]\{3,4\}$'
V domovském adresáři je soubor config s následujícím obsahem (řádky mají libovolné pořadí):
local_dir=~/project
filename=main.cpp
remote_host=u1-1.ms.mff.cuni.cz
remote_dir=~/Pascal/project
Do proměnných local_dir, filename, remote_host, remote_dir vložte hodnoty z config souboru (stačí provést vzorově pro jednu proměnnou).
filename=`grep filename= config | cut -d= -f2`
a obdobně pro další proměnné
V souboru s1 jsou uvedeny názvy adresářů. Vytvořte tyto adresáře a spočítejte, kolik z nich nemohlo být vytvořeno (např. protože již existovaly).
for i in `cat s1`; do mkdir $i 2>&1;done | wc -l
2>&1 přesměruje chybový výstup do standardního výstupu
Kolik různých login shellů se používá v souboru /etc/passwd ?
cat /etc/passwd | cut -f7 -d: | sort -u | wc -l
V souboru shells.denied jsou uvedeny zakázané login shelly. Zjistěte, které z nich jsou uvedeny v souboru /etc/passwd .
for i in `cat shells.denied`; do echo -n $i":";grep -c $i /etc/passwd;done | grep -v 0 | cut -f1 -d:
Máte k dispozici soubor s1 a soubor p, který obsahuje změny souboru s2 oproti souboru s1. Použijte vhodný příkaz, který provede změny v souboru s1 aby odpovídal souboru s2.
diff -c a b > p
patch -i p -o a
diff -c a b > p – vytvoří rozdílový soubor p obsahujíci změny souboru b oproti souboru a
patch -i p -o a – uplatní změny popsané v p do souboru a, čili soubor a se shoduje se souborem b
diff -c – určuje rozdíly s ohledem na kontext, ne na řádky jako obvykle
Pomocí příkazu scp přeneste soubory, jejichž seznam je uložen v souboru sources. Jméno uživatele pro vzdálený systém je v proměnné REMOTE_USER a název počítače je v proměnné REMOTE_HOST. Cesta na vzdáleném systému bude stejná jako aktuální.
for i in `cat sources`; do scp $i $REMOTE_USER@$REMOTE_HOST:$i;done
Z aktuálního adresáře vypište 5 největších obyčejných souborů (ideálně pouze jméno) končících na .avi . Výstup uložte do souboru max a zároveň jej připište za konec souboru /tmp/maxfiles .
find . -type f -name '*.avi' -ls | tr -s ' ' | sort -n -r -k7 | head -5 | cut -d':' -f2 | cut -c4- | tee max >> /tmp/maxfiles
Zaarchivujte obyčejné soubory v domovském adresáři (s relativní cestou), jejichž velikost je menší než 2000 znaků a jejichž jste vlastníci. Před archivací jim přidejte právo pro zápis pro sebe a svou skupinu.
FILES=`find ~ -type f -size -2000c -user $USER`
echo $FILES | xargs chmod ug+w
echo $FILES | xargs tar cvf files.tar
gzip files.tar
nebude fungovat pro velké množství souborů, protože se používá xargs, který předá všechny parametry najednou
Zaarchivujte obyčejné soubory v domovském adresáři (s relativní cestou), které jsou spustitelné vlastníkem. Archiv zkomprimujte.
find ~ -type f -executable | xargs tar cvf curdir.tar; gzip curdir.tar
V aktuálním adresáři smažte všechny soubory, jejichž název končí na text uvedený v souboru s1 (např. .jpg). Spočítejte počet neúspěšných pokusů o smazání souboru. (Předpokládejte, že nemáte alias rm='rm -i' .)
find ~ -type f -name "*`cat s1`" -exec rm -i {} 2>failed \;
cat failed | wc -l
Vypište z /etc/ssh/sshd_config poslední výskyt řetězce PermitRootLogin, před kterým se nenachází znak #
cat /etc/ssh/sshd_config | grep -v '^#' | fgrep PermitRootLogin
Spustěte program ./program s parametrem xyz a ověřte, jestli běží.
./program xyz
ps -o pid,ppis,comm | awk '/ .\/program$/ {print $1,$2}'
Bash hledá program, jehož jméno se shoduje s názvem příkazu v adresářích, které jsou uvedeny v proměnné PATH
Uložte původní hodnotu masky přístupových práv do proměnné OLD_MASK.
OLD_MASK=`umask`
Nastavte masku tak aby nově vytvořené soubory měly práva rw- r-- --- a adresáře měly práva rwx r-x ---.
umask 27
Vytvořte adresářovou strukturu (dále jen adresářovou strukturu – myslí se tato) podle následujícího schématu (YMMDD představuje aktuální datum ve formátu rokměsícden – použijte příkaz date).
backup-YYMMDD
+-- sources
| `-- include
`-- users
DIRNAME=backup-`date +%y%m%d`
mkdir -p "$DIRNAME/sources/include"
mkdir "$DIRNAME/users"
Do podadresáře users nakopírujte soubory /etc/passwd, /etc/group a vytvořte v něm soubor passwd.yp, který bude obsahovat tabulku passwd z NIS.
cp /etc/passwd /etc/group "$DIRNAME/users"
ypcat passwd > "$DIRNAME/users/passwd.yp"
Do podadresáře users nalinkujte (hardlink) soubor /etc/shadow .
ln /etc/shadow "$DIRNAME/users/"
Nastavte souborům passwd, passwd.yp a group taková práva, aby je mohl číst pouze vlastník (symbolicky/oktalově).
chmod u+r,g-r,o-r "$DIRNAME"/users/[pg]*"
chmod 600 "$DIRNAME"/users/[pg]*"
Na začátek souboru ~/my_script vložte řádku #!/bin/bash.
echo "#!/bin/bash" > ~/my_script2
cat ~/my_script >> ~/my_script2
mv ~/my_script2 ~/my_script
Přidejte tomuto souboru práva tak, aby byl skript (soubor) spustitelný pro vlastníka, ostatní práva neměňte.
chmod u+rx ~/my_script
Spusťte tento soubor na pozadí s argumenty c:\, c:\Program␣Files .
~/my_script 'c:\' 'c:\Program Files' &
Zjistěte, zda program běží, s jakým PID a PPID.
MYPID=`jobs -l | awk '{print $2}'`
ps -o pid,ppid | grep "^ *$MYPID "
Programem je skript, běží tedy jako proces shellu, ze kterého se spouští postupně jednotlivé části. Číslo procesu zjistíme příkazem jobs -l .
Za 5 minut programu pošlete signál SIGINT.
{ sleep 5*60; kill -INT $!; } &
celá sekvence příkazů je spuštěna na pozadí
$! – číslo posledně spuštěného procesu
pokud bychom spouštěli tento příkaz až po předchozím příkladu, muselo by tam být $MYPID místo $!
Do vytvořené adresářové struktury nakopírujte soubory z adresáře project (a jeho podadresářů) ve svém domovském adresáři, které nejsou prázdné a jejichž jméno končí na .c – podadresáře sources – nebo .h – do podadresáře include –, případné chyby zahoďte.
find ~ -type f ! -size 0 \( \( -name '*.c' -exec cp {} "$DIRNAME/a/sources" \; \) -o \( -name '*.h' -exec cp {} "$DIRNAME/sources/include" \; \) \)
Adresářovou strukturu zaarchivujte a zkomprimujte, při úspěchu ji nakopírujte na vzdálený počítač pod jménem uživatele v proměnné REMOTE_USER na počítač se jménem v proměnné REMOTE_HOST souboru /tmp/USERNAME.tgz (kde USERNAME je jméno aktuálního uživatele). V případě úspěšného přenosu archiv smažte z lokálního počítače.
tar cf - "$DIRNAME" | gzip > $USER.tgz && scp $USER.tgz "$REMOTE_USER@$REMOTE_HOST:/tmp" && rm $USER.tgz

Creative Commons License