# Úvod do UNIXu (SWI095x1h), 7. cvičení, 2005-04-06
# SU1, Malá Strana, MFF UK
#
# Řešení jsou odladěná na FreeBSD 4.11-RELEASE, případné konkrétní
# situace se týkají stroje mail.kolej.
#
# $DevNullCZ: cviceni-07.reseni.txt,v 1.3 2005/04/11 23:03:12 jp Exp $
#

#---------------------------------------------------------------------
# signály, procesy
#---------------------------------------------------------------------

(sp0) skripty, spouštění skriptů, použití "#!/bin/sh", ...

(sp1) příkaz ps, signály, návratová hodnota příkazů, $?, $$, ...

(sp2) vytvořte si skript, který si pojmenujte tak, aby nekolidoval se
jmény skriptů ostatních, nechte ho čekat a z druhé konzole ho
sestřelte. Na konzoli, kde jste skript spustili, ověřte návratovou
hodnotu skriptu pomocí promenné "?".

## # obsah skriptu:
## sleep 999
##
## ps -ax | grep <jmeno_skriptu>
## kill <pid>
##
## návratová hodnota při ukončení procesu signálem je 128 + číslo
## signálu; ověřte si to

Dále zkuste killnout proces někoho jiného (ps -ax), killnout si $$
pomocí signálu 15 a 9, vyberte sloupec výstupu příkazu ps.

## ps -ax | tr -s ' ' ' ' | cut -f4 -d' '

(sp3) napište skript, který po zaslání interrupt signálu (tj.
stisknutí ^C na konzoli, kde jste skript spustili) vypíše řetězec
"signal caught" a skončí. Čekání skriptu emulujte například pomocí
"sleep 999".

Hint: trap

## # obsah skript:
## trap "echo signal caught" 2
## sleep 999

(sp4) vypište seznam všech běžících procesů v systému tak, že
vypíšete pouze jejich PID a pak jméno příkazu, kterým byl proces
spuštěn

Hint: option '-o'

## ps -o 'pid,comm'

#---------------------------------------------------------------------
# emulace existujicích příkazů/voleb pomocí příkazů jiných
#---------------------------------------------------------------------

(e1) částečně emulujte "ls -lL" pouze pomocí "ls -l" a jiných
příkazů, které znáte; pořadí vypisovaných řádků nemusí být
zachováno, stejně jako nemusí být zachováno zarovnání sloupců a u
symlinků nemusí být ve výstupu jméno symlinku jako tomu je u "ls
-lL", ale může tam být celé jméno souboru, na který symlink ukazuje.

## ls -l | grep -v ^l
## ls -l | grep ^l | sed -e 's/.*-> \(.*\)$/\1/g' > tmp
##
## NEBO lépe, protože jméno symlinku může obsahovat "->" (i když
## používání speciálních znaků shellu ve jménech souborů
##  nedoporučuju):
## ls -l | grep ^l | tr -s ' ' ' ' | cut -f11 -d' ' > tmp
##
## cat tmp | xargs -L1 ls -l
## rm tmp

(e2) jako (e1), ale zachovejte pořadí řádků; různé zarovnání sloupců
opět ignorujte

Hint: sed '=', sort -n, paste

## # očísluj řádky
## ls -l | sed -e '=' | sed -e 'N; s/\n/ /' > tmp1
## # najdi symlinky
## cat tmp1 | grep -e '^[0-9]* l' > tmp.symlinks
## # najdi ostatní
## cat tmp1 | grep -v -e '^[0-9]* l' > tmp.others
## # zbav se hlušiny
## cat tmp.symlinks | sed -e 's/^\([0-9]*\).*-> \(.*\)$/\1 \2/' > tmp.symlinks2
## # vezmi čísla
## cat tmp.symlinks2 | cut -f1 -d' ' > tmp.numbers
## # vezmi soubory
## cat tmp.symlinks2 | cut -f2 -d' ' > tmp.files
## # dlouhý listing
## cat tmp.files | xargs -L1 ls -l > tmp.ls-l
## # spoj výstupy
## paste -d' ' tmp.numbers tmp.ls-l > tmp.paste
## # finální výstup
## cat tmp.paste tmp.others | sort -n | cut -f2- -d' '
## rm tmp.*
##
## NOTE: Pokud naleznete elegantnější řešení, určitě mi ho pošlete.
##

(e3) jako (e1) nebo (e2), ale výstup musí obsahovat jméno symlinku.

## zkuste si sami, pokud vyřešíte, pošlete mi řešení

#---------------------------------------------------------------------
# různé
#---------------------------------------------------------------------

(r1) napiště skript, který v aktuálním adresáři přejmenuje všechny
adresáře typu "_XXX" na "xxx"; například adresář "_INFO" změní na
"info". Přejmenování se týká pouze adresářů, ostatní soubory byť
vyhovujícího jména musí zůstat zachovány.

## jedno z mnoha možných řešení:
##
## find . -type d -name '_*' | sed -e 's/^\.\///' > tmp1
## cat tmp1 | sed -e 's/^_//' | tr '[:upper:]' '[:lower:]' > tmp2
## sed -i "" -e 's/^/mv /' tmp1
## paste -d' ' tmp1 tmp2 > tmp3
## sh tmp3
## rm tmp1 tmp2 tmp3