6. Bash a skripty

Test

Program tests aliasem [ ]umožňuje vyhodnocovat souborové typy a porovnávat hodnoty.

Test vrací (stejně jako jiné příkazy) hodnotu 0, pokud vše proběhlo v pořádku, tj. vyhodnocovaná podmínka je platná, 1 pokud podmínka neplatí a 2 pokud dojde k chybě (např. špatná syntaxe). Vzniká tak trochu paradoxní situace, kdy pro Bash je 0 pravda a 1 nepravda. Bližší informace viz:

man test

Možnosti uvození

Máme celkem čtyři možnosti uvození speciálních znaků, proměnných a příkazů:

Apostrofy (')

Řetězec uvedený mezi apostrofy, je interpretován jako text.

echo 'Hostname meho pocitace je $HOSTNAME' 

Uvozovky (")

Řetězec uvedený mezi uvozovky, je interpretován jako text se zachováním některých funkcí interpretu příkazů.

Vypnuto je nahrazování jmen, ale příkazy historie, proměnné, znaky uvozené zpětným lomítkem nebo obrácené apostrofy zůstávají nadále aktivní a budou interpretovány tak, jako kdybyste je zapsali přímo na příkazový řádek samostatně bez uvození.

echo "Hostname meho pocitace je $HOSTNAME" 

Zpětné lomítko (\)

Zpětné lomítko uvozuje vždy jeden znak, který je interpretován jako speciální. Například \usymbolizuje uživatelské jméno právě aktivního uživatele, \nzase nový řádek. Když budeme chtít vypsat obrácené lomítko, můžeme k tomu využít zápisu \\, pro apostrof \'a pro uvozovky pak zase \", čímž předejdeme tomu, aby interpret příkazů pokládal lomítko nebo apostrof, které chceme vypsat, za speciální přepínač.

Další důležitou vlastností zpětného lomítka je možnost vypnutí speciálního významu některých znaků. Pokud tedy zapíšeme \*nebo \~, budou znaky *~interpretovány jen jako obyčejné znaky bez jakéhokoliv nahrazování.

echo "Hostname meho pocitace je \"$HOSTNAME\"" 

Zpětné apostrofy (`)

Zpětné apostrofy `` umožňují předat výstup jednoho programu jako argument jinému programu, čili vlastně takový opak echa. Příkaz zadaný mezi zpětné apostrofy je tedy nahrazen svým výstupem (výstup je převeden na argumenty oddělenými mezerami a vypsanými na jednom řádku), který může být například předán ke zpracování dalšímu příkazu.

echo `ls /bin`

 Skripty

Můj první skript

Vytvořte textový soubor s libovolným názvem např. touch muj-prvni-skript.sha nastavte mu oprávnění pro spouštění tj. chmod +x muj-první-skript.sh.

Upravte obsah souboru např.:

#!/bin/bash
echo "Ahoj"

Skript spusťte příkazem ./mujprvni-skript.sh.

Zjištění existence souboru /etc/passwd

#!/bin/bash
if [ -e /etc/passwd ] ; then
  echo "Soubor s databází uživatelů existuje :)"
fi

Dávkový převod multimediálních formátů

Skript wmv2avi.sh dávkově převádí soubory z formátu wmv do avi. Úpravou nastavení ffmpeg je možné převádět i jiné formáty (video, audio).

#!/bin/sh
if [ -z "$1" ] ; then
  echo "Skript pro prevod WMV do AVI formatu"
  echo "Pouziti:"
  echo "wmv2avi adresar [clear]"
  exit 1
fi
if [ ! -d "$1" ] ; then
  echo "neexistuje adresar $1"
  exit 1
fi
for i in `find "$1" -type f -name '*.wmv'` ; do
  echo prevadim soubor $i
  ffmpeg -i $i `echo $i|sed 's/.wmv$/.avi/'`
done
exit 

Pravidelné oznamování data a času

Níže uvedený příklad oznámí každou celou hodinu aktuální datum a čas (ve čtvrt, v půl a ve tři čtvrtě hodiny pouze čas).

  1. Nainstalujte
    sudo apt-get install saydate saytime libsox-fmt-base libsox-fmt-oss
  2. V /home/user/bin vytvořte soubor timer.sh a nastavte mu oprávnění pro spouštění
    #!/bin/bash
    # say current date and time
    h=$(date +%M)
    if [ $h = 00 ]; then
      saydate -the_date_is -dow -day -month -year -and
    fi
    saytime -f %P%l%M -v 5 
  3. Do /etc/crontab vložte (opravte jméno uživatele)
    # say current date and time
    0,15,30,45 * * * * user /home/user/bin/timer.sh
    

 Dávková změna kódování

Pomocí příkazu iconv nebo convmv je možné změnit kódování souborů např. z Win-1250 na UTF-8:

for F in $(find $1 -iname "*.html")
do
  if [ -f $F ]; then
    iconv -f windows-1250 -t utf-8 $F > ${F}1
    mv ${F}1 $F
  fi
done

awk

Výběr požadovaných záznamů z TXT souboru a uložení jako CSV:

  • -F nastavení oddělovače na středník
  • $1 první sloupec
  • $0 celý řádek
awk -F ";" '{if ($1 ~ /’30’/) print $0}' source.txt > result.csv

source.txt

'10';'333a';'A'
'30';'444b';'B'
'30';'444c';'C'
'50';'555d';'D'

result.csv

'30';'444b';'B'
'30';'444c';'C'

Dávkové změny obrázků

Otočení obrázků obsahující EXIF informace:

  • automatické otočení všech fotek v aktuálním adresáři
  • jhead -autorot *.jp*

Změna velikosti obrázků:

  • je-li níže uvedený zápis spuštěn v adresáři s obrázky vytvoří nový adresář "width-1280" a do něj uloží kopie obrázků zmenšené na max. šířku 1280 px (uvedený příklad funguje na Mac OS X) – menší obrázky zvětší no (výhodnější je tedy použít GwenView)
  • mkdir width-1280; sips --resampleWidth 1280 --out width-1280 *.jpg
  • pro změnu velikosti na maximální rozměry můžete využít třeba níže uvedený skript, který po spuštění v aktuálním adresáři s obrázky vytvoří nový adresář "800x600max" a do něj uloží kopie obrázků zmenšené na max. rozměr 800 x 600 px
  • #!/bin/bash
    mkdir 800x600max
    for file in *.jp* ; do  
      convert $file -resize 800x600 -quality 80 800x600max/$soubor
    done
  • pro dávkové úpravy obrázků je pro KDE vhodná např. aplikace KIM (KDE Image Menu) nebo GwenView

ImageMagick

Balík příkazů určený zejména pro dávkové zpracování obrázků.

Vložení vodoznaku

Skript watermark.sh dávkově mění velikost JPG obrázků na max. velikost 800 px a přidává k nim obrázek vodoznaku watermark.png.

#!/bin/bash
# zobrazeni napovedy, pokud neexistuje prvni parametr
if [ -z "$1" ] ; then
  echo ""
  echo "Skript pro zmenu velikosti JPG obrazku na rozmery max. 800 px a pridani vodoznaku. Pouziti:"
  echo "./watermark.sh *.jpg"
  exit 1
fi
# vytvoreni adresare 800
if [ ! -d 800 ] ; then
  echo "Creating folder ./800/"
  mkdir 800
fi
for imgfile in $* ;do
  echo "Adding watermark to ./800/$imgfile"
  bn=`basename "$imgfile"`
  #dn=`dirname "$imgfile"`
  outfilename="800/t_$bn"
  convert -geometry 800x800 -density 96 -quality 85% -format jpg "$imgfile" "$outfilename"
  composite -watermark 30x30 -gravity NorthWest watermark.png "$imgfile" "$outfilename"
  composite -watermark 30x30 -gravity NorthEast watermark.png "$outfilename" "$outfilename"
  composite -watermark 30x30 -gravity Center watermark.png "$outfilename" "$outfilename"
  composite -watermark 30x30 -gravity SouthWest watermark.png "$outfilename" "$outfilename"
  composite -watermark 30x30 -gravity SouthEast watermark.png "$outfilename" "$outfilename"
done