Seminár k operačným systémom: Cvičenie 9 [komplexné skripty, správa jobov]

Galéria súborov

Stiahnime 4 obrázky z webu:

wget http://images2.fanpop.com/images/photos/8100000/Christmas-Tree-Wallpaper-christmas-8142630-1024-768.jpg -O image1.jpg
wget http://latestsdaily.com/wp-content/uploads/2013/12/merry-christmas.gif -O image2.jpg
wget http://www.hdwallpapersinn.com/wp-content/uploads/2013/11/linux-christmas1.jpg -O image3.jpg
wget http://images.fanpop.com/images/image_uploads/Snoopy-Christmas-peanuts-452770_1280_960.jpg -O image4.jpg

Premenujme:

mv image1.jpg 'image 1.jpg'
mv image2.jpg 'image 2.jpg'
mv image3.jpg 'image 3.jpg'
mv image4.jpg 'image 4.jpg'

Ak súbor obsahuje medzery, musíme ho uviesť do apostrofov/úvodzoviek.

Vytvorme galériu súborov:

#!/bin/sh

# pre subor /tmp/xmas/santa-claus.jpg -> santa-claus.html

daj_html() {
        NAZOV_SUBORU="$1"

        if [ -z "$NAZOV_SUBORU" ]
        then
                exit 1
        fi

        NAZOV_SUBORU=${NAZOV_SUBORU##*/}
        NAZOV_SUBORU=${NAZOV_SUBORU%.*}
        echo "$NAZOV_SUBORU.html"
}

for SUBOR in /tmp/xmas/*.jpg
do
        HTML=${SUBOR##*/}
        HTML=${HTML%.*}

        PREDCHODCA=$(ls /tmp/xmas/ -1 | grep "$HTML" -B1 | grep -v "$HTML")
        NASLEDOVNIK=$(ls /tmp/xmas/ -1 | grep "$HTML" -A1 | grep -v "$HTML");

        PREDCHODCA=$(daj_html "$PREDCHODCA")
        NASLEDOVNIK=$(daj_html "$NASLEDOVNIK")

        VYSTUP=~/public_html/galeria/$HTML.html

        echo "<h1>$HTML</h1>" > $VYSTUP
        if [ -n "$PREDCHODCA" ]
        then
                echo "<a href='$PREDCHODCA'>PREDOSLY</a>" >> $VYSTUP
        fi

        if [ -n "$NASLEDOVNIK" ]
        then
                echo "<a href='$NASLEDOVNIK'>NASLEDOVNIK</a>" >> $VYSTUP
        fi

        # echo "<h1>$HTML</h1> <a href='$PREDCHODCA'>PREDOSLY</a> <br />   <img src='${SUBOR##*/}' />" > ~/public_html/galeria/$HTML.html
        echo "<img src='${SUBOR##*/}' />" >> $VYSTUP

        cp "$SUBOR" ~/public_html/galeria
done
  • využijeme for iterujúci cez názvy súborov.
    • hviezdičková expanzia in /tmp/xmas/*.jpg funguje aj pre súbory s medzerami
  • využijeme pestrú paletu expanzií: percentovú, dvojmrežové

Vlastné funkcie

  • vlastné funkcie sa tvária ako skripty
  • hlavička:

    daj_html()

  • hlavička nemá ani def, ani function

  • žiadne deklarácie dátových typov: v shelli neexistujú
  • žiadne parametre: riešia sa premennými $1, $2
    • v rámci funkcie vieme pristupovať k týmto parametrom podobne ako z bežného skriptu
    • tieto premenné sú “lokálne”, prekryjú význam rovnakých premenných z vonkajšieho skriptu
  • vracať sa môže len exit kód (celé číslo medzi 0 a 255, v praxi medzi 0 a 125, viď Wikipedia)
    • funkcia môže vracať len exit kód tak ako shellskript.
  • môže len zapisovať do výstupov
  • možno použiť fintu s vyhodnotením premennej:

    scitat() {
            [ -n "$1" ] || return 1
            [ -n "$2" ] || return 2
    
            echo $(( $1 + $2 ))
    }
    
    echo "Scitavam" $(scitat 2 2)
    

Vstupy a výstupy

Štandardný výstup

  • Bežný program zapisuje do štandardného výstupu
    • špeciálny súbor stdout
    • obvykle je spriahnutý s obrazovkou: čo sa zapíše do stdout, ide na obrazovku
    • v Jave: System.out.println()
    • v C: súbor stdout, resp. implicitný pri funkciách typu printf(), resp puts()
  • štandardný výstup možno presmerovať do súboru

    echo "Hello World" > echo.txt
    
    • súbor sa prepíše s každým spustením
  • možno pripájať (append) k súbor cez >>
  • výstup možno potlačiť presmerovaním do špeciálneho súboru /dev/null
    • čierna diera: všetko, čo sa doň zapíše, sa zahodí
    • mnoho štandardných nástrojov má parameter -q (quiet) pre tichý mód, ale niekedy to nepomôže

Chybový výstup

  • programy majú k dispozícii druhý kanál na zápis: chybový výstup
    • špeciálny súbor stderr
    • tiež spriahnutý s obrazovkou
    • v Jave: System.err.println()
    • v C: súbor stderr
  • demo:

    novotnyr@s:~$ find / '*' | wc -l
    find: `/tmp/mc-root': Permission denied
    find: `/tmp/mlacko/public_html': Permission denied
    
    • find hľadá súbory, ale správy o odopretí prístupu posiela na stderr
    • neexistuje -q
  • presmerovať chybový výstup môžeme takto:

    find / '*' 2> /dev/null | wc -l
    
    • 2> presmeruje “druhý kanál”, čo je stderr do čiernej diery
    • 1> je stdout
  • presmerovať oba výstupy môžeme cez jednoduchý zobák.

Spúšťanie procesov na pozadí

Použitie ampersandu

Ľubovoľný proces môžeme spustiť na pozadí cez ampersand:

novotnyr@s:~$ find / '*' 2> /dev/null | wc -l &
[1] 31314

Náš proces sa stane jobom: po spustení sa rozbehne na pozadí, a dostane číslo “1” a PID 31314.

Po dobehnutí vypíše výsledok a uvidíme stav dobehnutia:

[1]+  Done                    find / '*' 2> /dev/null | wc -l

Pozor, joby nesmú kontinuálne niečo vypisovať: bude sa to miešať s terminálom a môžeme si dostať terminál do nepoužiteľného stavu. Zlá ukážka:

yes &

Vždy presmerujme výstupy do súboru! Nezmyselný, ale správny príklad:

yes > /dev/null &

Odoslanie jobu z popredia na pozadie

Bežiaci job môžeme poslať na pozadie cez Ctrl+Z. Uvidíme:

[1]+  Stopped                 find / '*' 2> /dev/null | wc -l

Rozbehnúť na pozadí ho môžeme cez bg:

[1]+ find / '*' 2> /dev/null | wc -l &

Zoznam jobov

Zoznam jobov môžeme pozrieť cez

jobs

Pozor! Nefunguje to krížom cez rôzne terminály (= rôzne inštancie putty)

Vyzdvihnutie jobu z pozadia na popredie

Job môžeme z pozadia dostať na popredie:

fg

Alternatívne:

`fg %2` 

Zoberie na popredie job číslo 2.

Zabitie jobu

  • Zabiť job č. 3 môžeme cez

    kill %3
    

Joby, ktoré prežijú odhlásenie

Ak chceme, aby job prežil odhlásenie z terminálu:

novotnyr@s>  nohup yes &

[1] 31897
nohup: ignoring input and appending output to `nohup.out'

Príkaz nohup sa postará o presmerovanie výstupov do textového súboru

Slušné správanie k stroju

  • úlohy na pozadí často nepotrebujú plnú pozornosť
  • “spustíme, odídeme spať, ráno máme výsledok”
  • nice: “buď milý k systému”

    nohup nice yes &
    
  • pridelí procesu nižšiu prioritu vykonávania.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *