Shell Prakticky
Složené příkazy v shellu

Lukáš Bařinka

Cíl

Cílem je vyzkoušet si řídící konstrukce v shellu (podmínka, cyklus)

Obsah

  • Cykly
  • Větvení

Část 1

Cykly

Úloha 01

Vytvořte proměnnou ALPHA, která obsahuje jednotlivé řádky s písmeny AZ.


							~ALPHA=$( printf '%s\n' {A..Z} )

							~printf -v ALPHA '%s\n' {A..Z}
							~ALPHA=${ALPHA%?}
						

Úloha 02

Pomocí proměnné RANDOM vypište náhodný řetězec náhodné délky (max. 10 znaků).

Použijte přitom proměnnou ALPHA .


							~A=$( wc -l <<< "$ALPHA" )
							(( L = RANDOM%10 + 1 ))
							for (( i=1; i<=L; i++ )); do
								R=$(( RANDOM%A + 1 ))
								printf '%c' $( sed -n "${R}p" <<< "$ALPHA" )
							done
							~printf '\n'
						

Úloha 03

Spusťte příkaz date 2x těsně za sebou a zjistěte, zda se výstupy liší. Totéž proveďte 1000x a spočítejte (vypište) kolikrát se výstup lišil.


							~C=0
							~for (( i=1; i<=1000; i++)); do
								A=$(date)
								B=$(date)
								[ "$A" != "$B" ] && (( C++ ))
							done
							~echo "$C"
						

Úloha 04

Zkuste vyřešit předchozí úlohu bez testování shody výstupů dvou příkazů date (příkazem test/[).


							~C=0
							~U=$(
								for (( i=1; i<=1000; i++)); do
									{ date; date; } | uniq
								done | wc -l
							)
							~echo $(( U - 1000 ))
						

Úloha 05

Vytvořte proměnné X a O obsahující řetězce \|/- , resp.  .,oOo,. .


							~X='\|/-' O=' .,oOo,.'
						

Úloha 06

S prodlevou 0.1s přepisujte cyklicky jednotlivé znaky z obou proměnných na terminálu. Podřetězec proměnné se vypíšt pomocí ${prom:od:pocet} . Znak smažete pomocí '\b' .


							~while sleep 0.1; do
								printf '\b\b\b%s %s' \
									"${X:$(( ++x % ${#X} )):1}" \
									"${O:$(( ++o % ${#O} )):1}"
							done
						

Úloha 07

Pro každou položku v aktuálním adreáři vypište jeden řádek s její velikostí (v bytech) a jejím jménem odděleným tabulátorem.

Nepoužívejte příkaz ls, ale příkaz stat .


							~stat -c '%s   %n' *

							~for file in *; do
								size=$( stat -c %s "$file" )
								printf '%d\t%s\n' "$size" "$file"
							done
						

Úloha 08

Do výstupu předchozí úlohy přidejte nakonec součet velikostí a slovo total a velikosti zformátujte na jednotnou šířku.


							~output= sum=0
							~for file in *; do
								size=$( stat -c %s "$file" )
								(( sum += size ))
								printf -v out '%d/%s/' "$size" "$file"; output+=$out
							done
							~printf -v out '%d/%s\n' "$sum" total; output+=$out
							~oldIFS=$IFS IFS=/
							~printf "%${#sum}d %s\n" $output
							~IFS=$oldIFS
						

Část 2

Větvení

Úloha 09

Vypište velikost největšího obyčejného souboru v aktuálním adresáři (nepoužívejte výstup příkazu ls).


							~max=0
							~for file in *; do
								if [ -f "$file" -a ! -L "$file" ]; then
									size=$( stat -c %s "$file" )
									(( size > max ? max=size : max ))
								fi
							done
							~printf '%d\n' "$max"

							~stat -c %s * | sort -n | tail -n 1
						

Úloha 10

Vypište název největšího obyčejného souboru v aktuálním adresáři (nepoužívejte výstup příkazu ls).


							~max=0 name=
							~for file in *; do
								if [ -f "$file" -a ! -L "$file" ]; then
									size=$( stat -c %s "$file" )
									(( size > max )) && max=$size name=$file
								fi
							done
							~printf '%s\n' "$name"
						

Úloha 11

Pro každou položku z aktuálního adresáře vypište informaci o typu souboru ('soubor', 'adresar' nebo 'jiny') a jméno oddělené tabulátorem.


							~for file in *; do
								type=$( LC_ALL=C stat -c %F "$file" )
								case $type in
									regular*) T=soubor;;
									directory) T=adresar;;
									*) T=jiny;;
								esac
								printf '%s\t%s\n' "$T" "$file"
							done