Seminár k operačným systémom: Cvičenie 6 [Bash II.]

Nájdite u nejakého používateľa na serveri nejaký Java projekt

find /home -name '*.java'
  • find potrebuje dva parametre:
    • počiatočný adresár
    • predpis (pattern) pre názov súboru uvedený za parametrom -name
      • hodnota parametra musí byť uvedená v apostrofoch, aby sme zabránili neželanej expanzii shellu
      • ak parameter -name vynecháme, nastanú podivné správania:
      • zlé príklady použitia:
        • find /home *.java expanduje reťazec *.java na názvy všetkých súborov v aktuálnom adresári s príponou java. Ak sa také súbory nenájdu, hľadá sa v adresári s názvom “hviezdička bodka java” a v adresári /home akýkoľvek súbor
        • find /home '*.java' hľadá v adresári s názvom “hviezdička bodka java” a v adresári /home akýkoľvek súbor
        • find /home -name *.java expanduje reťazec *.java na názvy všetkých súborov v aktuálnom adresári s príponou java. Ak sa také súbory nenájdu, hľadajú sa v adresári /home súbory s príponou java. Ak sa v aktuálnom adresári nachádzajú nejaké java súbory, vďaka expanzii nastane veľmi podivné správanie

Alternatívne cez locate

locate '*.java'

Na mnohých moderných systémoch je k dispozícii vyhľadávanie s použitím indexu nástrojom locate. (Index sa buduje automaticky, obvykle raz za deň, s použitím nástroja updatedb).

Nájdite v adresári s Java zdrojákmi názvy všetkých verejných tried

find . -name *.java -exec grep 'public class' {} \; | sed 's#public class \([^ ]*\).*#\1#'

Alternativne: zoberiem tretie slovo

find . -name '*.java' -exec grep 'public class' {} \; | cut -d' ' -f3

Demonštrujte rozličné prípady použitia expanzie reťazcov

Bare words, nahé slová

echo Ahoj svet

echo berie dva parametre, teda dve shellslová: Ahoj a svet

Nahé slová s výkričníkom

echo Ahoj svet!

echo berie opäť dva parametre, teda dve shellslová: Ahoj a svet!

Úvodzovky

echo "Ahoj svet"

echo berie jeden parameter, teda jedno shellslovo, v jeho vnútri je medzera

Úvodzovky s výkričníkom

echo "Ahoj svet!"

bash vypíše -bash: !": event not found. echo síce dostane na vstup jedno shellslovo s mezerou, ale v jeho vnútri, keďže je v úvodzovkách, prebehne expanzia. Výkričník v bashi vyvolá históriu príkazov — v tomto prípade sa snaží nájsť príkaz začínajúci sa úvodzovkou (nepýtajte sa…)

Apostrofy s výkričníkom

echo 'Ahoj svet!'

echo berie jeden parameter, teda jedno shellslovo, v jeho vnútri je medzera. Vďaka apostrofom neprebehne žiadna expanzia.

Expanzia premenných v úvodzovkách

echo "Ahoj svet, som v $PWD"

na vstup príde jedno shellslovo, ale premenná $PWD sa expanduje na meno aktuálneho adresára.

Apostrofy bez expanzie premenných

echo 'Ahoj svet, som v $PWD '

apostrofy zabraňujú akejkoľvek expanzii; znamenajú “nedotýkaj sa môjho reťazca”. Na konci reťazca bude “dolár, P, W, D”.

Úvodzovky a zrušenie expanzie výkričníka

echo "Ahoj svet! "
  • v bashi prebehne expanzia výkričníka, ale keďže žiadny príkaz v histórii nezačína medzerou, nestane sa nič a vypíše sa Ahoj svet!.

Nájdite v JAR archíve danú triedu

CLASSNAME=String; unzip -ql rt.jar | grep -i /$CLASSNAME.class

Vypíšte názvy tried v danom JAR archíve

unzip -ql archive.jar | tail -n+3 | head -n-2 | sed -e 's#.*/##' -e '/^$/d'

Alternatívne:

unzip -qql archive.jar | sed -e 's#.*/##' -e '/^$/d'

Zo súboru vo formáte Markdown automaticky vygenerujte obsah

grep -E '^[-=]{2}' -B1 cvicenie2.md | grep -v '^--$' | pandoc -r markdown -w html -o cvicenie2-toc.html

alebo

grep -E '^---|^===' -B1 /tmp/cvicenie2.md | grep -v '^--$' | pandoc -r markdown -w html -o obsah.html

Vytvorte skript, ktorý pre zadaného používateľa vráti jeho domovský adresár

Riešenie:

if [ -z "$1" ]
then
        USER=$(id -un)
else
        USER=$1
fi

grep $USER /etc/passwd | cut -d: -f6
  • pri testovaní prázdnoty reťazca cez -z vždy uzatvárajme premennú do úvodzoviek

    • pri nedefinovanej premennej môžu nastať psie kusy
    • výraz pri nedefinovanej premennej sa expanduje na

      [ -z ]
      
    • toto je vždy “pravda”

    • premenná $1 je zhodou okolností vždy definovaná, aj keď prázdna

Oveľa kratšie riešenie s expanziou premenných:

USER=${1:-$(id -un)}
grep $USER /etc/passwd | cut -d: -f6

Zistite aktuálny kurz dolára voči euru

wget -O - -q http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml | grep USD | cut -d"'" -f4        
  • wget
    • -O -: presmeruje výstup wgetu na štandardný výstup
    • -q: zakáže všetky logovacie hlášky
  • grep:
    • nájdeme príslušný riadok
  • cut:
    • rozdelíme výstup podľa apostrofu (XML atribúty sú v apostrofoch)
    • vytlačíme príslušnú položku

Zistite, v ktorých runleveloch sa spúšťa zadaná služba

#!/bin/sh
SERVICE=bootlogs
echo $SERVICE

for FOLDER in /etc/rc?.d
do
        RUNLEVEL=$( echo $FOLDER | cut -c8 )
        FILE=$FOLDER/S??$SERVICE
        if [ -e "$FILE" ]
        then
                echo "$RUNLEVEL"
        else
                echo "-"
        fi
done | xargs
  • hojne využívame shellovú expanziu:
    • vieme, že skripty pre štart služby sú predpísaných adresároch, napr. pre runlevel 0 v /etc/rc0.d
    • skript v adresári pre štart služby začína na S, nasleduje dvojciferné číslo poradia a názov služby.
    • pomocou xargs vieme previesť text v riadkoch pod sebou na slová vedľa seba

Pridaj komentár

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