Shell Prakticky
Zpracování příkazové řádky

Lukáš Bařinka

Cíl

Cílem je zopakování jednoduchých příkazů a vyzkoušení si důsledků interpretace příkazové řádky.

Obsah

  • Základy
  • Pokročilejší příklady

Část 1

Základy

Úloha 01

Na standardní výstup vypište přesně, jak je zadáno:

Tento retezec obsahuje    7 mezer.
SP # Shell Prakticky
$SP$
`SP'
"SP"
'SP'
`\$/'
"$PATH"

							~printf '%s\n' 'Tento retezec obashuje    7 mezer.' \
							'SP # Shell Prakticky' '$SP$' '`SP'\' '"SP"' "'SP'" '`\$/'\' \
							'"$PATH"'
						

Úloha 02

Vypište počet aktuálně přihlášených uživatelů, zarovnaný mezerami zleva na 79 znaků.


							~printf '%79d\n' $( who | wc -l )
						

Úloha 03

Vypište počet aktuálně přihlášených uživatelů tak, aby číslo bylo zleva doplněno nulami na 10 číslic.


							~printf '%010d\n' $( who | wc -l )
						

Úloha 04

Vypište text Casova znacka: YYYYMMDD-hhmm, podle aktuálního data a času.


							~printf 'Casova znacka: %s\n' "$( date +%Y%m%d-%H%M )"
							~date +'Casova znacka: %Y%m%d-%H%M'
						

Úloha 05

Znovu vypište text Casova znacka: YYYYMMDD-hhmm, podle aktuálního data a času.


							~printf 'Casova znacka: %s\n' "$( date +%Y%m%d-%H%M )"
							~!!
						

Úloha 06

Do proměnné D uložte aktuální datum ve formátu YYMMDD. Vytvořte adresář backup_YYMMDD, kde YYMMDD je z proměnné D. Zobrazte podrobnosti vytvořeného adresáře a poté jej smažte.


							~D=$( date +%y%m%d )
							~mkdir "backup_$D"
							~ls -ld "backup_$D"
							~rmdir "backup_$D"
						

Úloha 07

V předchozím příkladu uložte řetězec backup do proměnné B a použijte ji.


							~B=backup
							~D=$( date +%y%m%d )
							~DIR=${B}_$D
							~mkdir "$DIR"
							~ls -ld "$DIR"
							~rmdir "$DIR"
						

Úloha 08

Podle aktuálního data vytvořte adresář YYYY a v něm adresář MM. V tomto adresáři vytvořte soubor DD.txt, který bude obsahovat aktuální čas.


							~YM=$( date +%Y/%m )
							~D=$( date +%d )
							~mkdir -p "$YM"
							~date +%T > "$YM/$D.txt"
						

Úloha 09

V adresáři podle předchozího příkazu vytvořte další, prázdné, soubory od 01.txt až po 31.txt.


							~touch "$YM"/{01..31}.txt
						

Úloha 10

Zobrazte všechna jména souborů v aktuálním adresáři, která obsahují řetězec uložený v proměnné FRAGMENT. (Před i za tedy může být libovolný počet znaků.


							~ls *"$FRAGMENT"*
							~printf '%s\n' *"$FRAGMENT"*
						

Úloha 11

Vypište všechny jména souborů v adresáři /bin, které:

  1. mají právě 3 znaky
  2. mají alespoň 3 znaky
  3. mají maximálně 3 znaky
  4. mají právě 2 znaky a začínají na malé písmeno
  5. mají právě 2 znaky a nezačínají na malé písmeno
  6. obsahují číslici
  7. mají právě 2 znaky a obsahují číslici
  8. obsahující ne-alfanumerický znak
  9. jsou adresáře

							~cd /bin
							~ls -d ???                        #1
							~ls -d ???*                       #2
							~ls -d ? ?? ???                   #3
							~ls -d [a-z]?                     #4
							~ls -d [[:lower:]]?
							~ls -d [^a-z]?                    #5
							~ls -d [^[:lower:]]?
							~ls -d *[0-9]*                    #6
							~ls -d *[[:digit:]]*
							~ls -d [0-9]? ?[0-9]              #7
							~ls -d [[:digit:]]? ?[[:digit:]]
							~ls -d *[^a-zA-Z0-9]*             #8
							~ls -d *[^[:alnum:]]*
							~ls -d */                         #9
						

Úloha 12

Vypište podrobný seznam všech adresářů (jako položky) uvedených v proměnné PATH.


							~oldIFS=$IFS; IFS=:; ls -ld $PATH; IFS=$oldIFS
						

Úloha 13

Vypište podrobný seznam všech položek adresářů uvedených v proměnné PATH.


							~oldIFS=$IFS; IFS=:; ls -l $PATH; IFS=$oldIFS
						

Úloha 14

V proměnné SERVER je uložen řetězec (např. localhost) a v proměnné USER jiný řetězec (např. osboxes). Zkopírujte všechny soubory z aktuálního adresáře, včetně případných podadresářů, na vzdálený počítač daný hodnotou proměnné SERVER do domovského adresáře uživatele jako uživatel podle hodnotoy proměnné USER.


							~scp -r * "$USER@$SERVER:"
						

Úloha 15

Zkopírujte všechny soubory, jejichž jméno končí na .pdf v aktuálním adresáři na vzdálený počítač localhost do stejného adresáře, jako je současný aktuální adresář (předpokládejte, že existuje).


							~scp *.pdf localhost:"$PWD"
						

Část 2

Aritmetika

Úloha 01

Vytvořte soubor s1, který bude obsahovat 10 řádek s čísly od 1 do 10.


							~printf '%d\n' {1..10} >s1
						

Úloha 02

Vytvořte soubor s2, který bude obsahovat 26 řádek s písmeny od a do z.


							~printf '%s\n' {a..z} >s2
						

Úloha 03

Do proměnné l1 uložte počet řádek souboru s1 a do proměnné l2 uložte počet řádek souboru s2.


							~l1=$( wc -l <s1 )
							~l2=$( wc -l <s2 )
						

Úloha 04

Do proměnné sum uložte součet počtu řádků souborů s1 a s2.


							~(( sum = l1 + l2 ))
						

Úloha 05

Pokud je v proměnné sum hodnota 36, vypište text: OK.


							~(( sum == 36 )) && echo OK
						

Část 3

Kostky

Úloha 06

Existuje proměnná RANDOM, která obsahuje náhodné číslo. Pokud je toto číslo sudé, vypište řetězec SUDA, pokud je liché, vypište řetězec LICHA.


							~sl=SUDA; (( RANDOM % 2 )) && sl=LICHA; echo "$sl"
						

Úloha 07

V předchozím příkladu vypište před řetězec i porovnávanou hodnotu.


							~sl=SUDA; (( R = RANDOM, R % 2 )) && sl=LICHA; echo "$R $sl"
						

Úloha 08

Vytvořte alias dice, který vypíše náhodně číslo od 1 do 6. Alias zavolejte a vypište.


							~alias dice='echo $(( RANDOM % 6 + 1 ))'
							~dice
							~alias dice
						

Úloha 09

Vytvořte alias roll, který hodí 3x kostkou a vypíše součet hodů.


							~alias roll='echo $(( $(dice) + $(dice) + $(dice) ))'
						

Úloha 10

Upravte předchozí alias roll tak, aby zobrazil také mezivýsledky, např.: 2 + 6 + 1 = 9


							~alias roll='(( a=$(dice), b=$(dice), c=$(dice), s=a+b+c ))
							echo $a + $b + $c = $s'
						

Část 4

Karty

Úloha 11

Vypište znak s Unicode U+2665.


							~echo $'\u2665'
						

Úloha 12

Vypište znaky s Unicode U+2660, U+2665, U+2666, U+2663, U+2664, U+2661, U+2662, U+2667.


							~echo $'\u2660' $'\u2665' $'\u2666' $'\u2663' $'\u2664'\
							$'\u2661' $'\u2662' $'\u2667'
						

Úloha 13

Vypište všechny karty, tedy hodnoty od 2 do 10, J, Q, K a A.


							~echo {{2..10},J,Q,K,A}\
							{$'\u2660',$'\u2665',$'\u2666',$'\u2663',$'\u2664',\
							$'\u2661',$'\u2662',$'\u2667'}
						

Úloha 14

Spočítejte počet karet.


							~printf '%s\n' {{2..10},J,Q,K,A}\
							{$'\u2660',$'\u2665',$'\u2666',$'\u2663',$'\u2664',\
							$'\u2661',$'\u2662',$'\u2667'}\
							| wc -l
						

Úloha 15

Vypište karty všechny karty tak, aby každá karta zabírala stejný počet znaků.

Pozor, některé znaky mohou být na více bajtů.


							~printf '%5s' {{2..10},J,Q,K,A}\
							{$'\u2660',$'\u2665',$'\u2666',$'\u2663',$'\u2664',\
							$'\u2661',$'\u2662',$'\u2667'}
						

Úloha 16

Řádky z předchozího příkladu uložte do proměnné cards.


							~cards=$( printf '%5s' {{2..10},J,Q,K,A}\
							{$'\u2660',$'\u2665',$'\u2666',$'\u2663',$'\u2664',\
							$'\u2661',$'\u2662',$'\u2667'} )

							#nebo lépe

							~printf -v cards '%5s' {{2..10},J,Q,K,A}\
							{$'\u2660',$'\u2665',$'\u2666',$'\u2663',$'\u2664',\
							$'\u2661',$'\u2662',$'\u2667'}
						

Úloha 17

Z proměnné je možné vypsat podřetězec pomocí syntaxe ${prom:start:len}, kde prom je jméno proměnné, start je výchozí pozice číslovaná od 0 a len je délka podřetězce. Vypište náhodnou kartu.


							~echo "${cards:$(( RANDOM % 104 * 3)):3}"
						

Úloha 18

Vytvořte alias card, který výpíše náhodnou kartu.


							~alias card='echo "${cards:$((RANDOM % 104 * 3)):3}"'
						

Úloha 19

Vytvořte alias gcard, který zobrazí grafickou podobu náhodné karty ve tvaru:


							.----.
							|    |
							|    |
							|  Q♤|
							'----'
						

							~alias gcard="printf '.----.\n|    |\n|    |\n| %s|\n'\'"\
							"----'\''\n' \"\$(card)\""
						

Úloha 20

Příkaz column dokáže vytvořit sloupce textu o zadané šířce. Uložte do souboru hand pět karet zasebou. Pomocí příkazu column vypište karty vedle sebe.


							~gcard >hand
							~gcard >>hand
							~gcard >>hand
							~gcard >>hand
							~gcard >>hand
							~column -c 40 hand
						

Úloha 21

Z předchozího příkladu vytvořte alias give, který rozdá 5 náhodných karet.


							.----.	.----.	.----.	.----.	.----.
							|    |	|    |	|    |	|    |	|    |
							|    |	|    |	|    |	|    |	|    |
							|  J♠|	|  3♤|	|  5♣|	|  K♧|	|  7♦|
							'----'	'----'	'----'	'----'	'----'
						

							~alias give='gcard >hand; gcard >>hand; gcard >>hand;
							~gcard >>hand; gcard >>hand; column -c 40 hand'