BOURNE SHELL PROGRAMOZÁS
 
 

A BUROK VÁLTOZÓI
 
 

A Shell a parancssor argumentumait sorszámmal azonosítja és string formában tartja számon. Az i-edik argumentumot tehát $i hivatkozással lehet elérni.
 
 

$# - az argumentumok száma
$* - a parancssor minden argumentuma
$- - a burok által adott opciók
$$ - a burok folyamatazonosítója
$! - az utolsó, &-el indított folyamat azonosítója

HOME - a cd parancs default értéke, a felhasználó saját (bejelentkezési) katalógusára állítja be a rendszer
PATH - a parancsok keresési útvonalat állítja be, azaz hogy a shell hol keresse a végrehajtandó fájlokat. Az egyes elemeket : választja el egymástól. A kurrens katalógus jele a . karakter.
CDPATH - a cd parancs szamara beállítható keresési útvonal, szinten kettõsponttal elválasztva. Ha e változó be van állítva, relatív elérési útvonalak megadásakor a shell megpróbálja illeszteni az általunk begépelt relatív nevet, és ha talált ilyet, oda vált.
MAIL - az e-mail postaüzeneteket tároló katalógus neve
MAILCHECK - megadja másodpercekben, hogy milyen gyakran ellenõrizze és írja ki a shell az új posta érkezését. Alapértelmezése 600. Ha értéke 0, minden parancs kiadása után, a prompt kiírása elõtt ellenõriz.
PS1, PS2 - az elsõdleges és másodlagos prompt. A default értékek a $ illetve a > karakterek.
TERM - a felhasználó által használt terminál típusa
LOGNAME - a felhasználó bejelentkezési azonosítója
IFS - a belsõ mezõhatárolók: azon karakterek, amelyek a shell szavait elválasztják (default megadása a szóköz, a tabulátor és az újsor karakterek
TZ - a helyi idõzóna
 
 

A BUROKVÁLTOZÓK ÉRTÉKADÁSA
 
 

$var          - var értéke; semmi ha var nincs deklarálva

${var}            - u.a.; hasznos, ha alfanumerikus karakterek követik a változó nevet

${var:-dolog}  - var értéke, ha definiálva van, egyébként dolog. $var változatlan

${var:=dolog}  - var értéke, ha definiálva van, egyébként dolog. Ha var nincs definiálva, akkor értéke dolog lesz.

${var:?uzenet} - ha var definiálva van, akkor var értéke, ha nem, akkor kiírja az üzenetet és a burok kilep. Ha az üzenet üres, kiírja, hogy var:parameter

${var:+dolog}  - dolog, ha var definiálva van, egyébként semmi
 
 

A set parancs kiírja az összes változó értéket.
 
 

Példák
 

1.

$ cat > argum
  echo " A teljes parancssor: $0 $* "
  echo " A parameterek szama ebben a sorban: $# "
  echo " Az elso parameter: $1"
CTRL-D
$ chmod +x argum
$ argum 'elso masod' harmad
  A teljes parancssor: argum elso masod harmad
  A paraméterek száma ebben a sorban: 2
  Az elso parameter: elso masod
$
 

2.
$ cat >fordit
  echo $3 $2 $1
CTRL-D
$ chmod +x fordit
$ fordit A B C
  C B A
$ fordit A
  A
$ fordit A B C D
  C B A
 
 

SHELL VALTOZÓK EXPORTJA
 

Egy létrehozott shell változó mindig ahhoz a shell-hez tartozok, amelyik létrehozta és a shell gyermekeinek, tehát a shell által indított programoknak nem adódik át automatikusan.

Ha azt akarjuk, hogy egy változót a leszármazott proceszek is megkapjanak, azt exportálni kell.

Példák.
 

1.
$ x = Hello
$ echo $x
  Hello
$ sh        # uj shell inditasa
$ echo $x
$ exit      # most vissza az elozo shell-be
$ echo $x
  Hello
$
 

2.
$ x=Hello
$ echo $x
  Hello
$ echo ${y-abc}
  abc
$ echo ${y=abc}
  abc
$ echo $y
  abc
$ echo ${z?szoveg}
  z: szoveg
$ echo ${a+szoveg}
$ echo ${x+szoveg}
  szoveg
$

 

3. Írjuk ki a képernyõre:

  Most a ...ban vagyok.

ahol a pontok helyére a HOME változó tartalma kerüljön.

$ echo "Most a ${HOME}ban vagyok."
$ echo "Most a $HOME ban vagyok.
$ echo Most a $HOME ban vagyok

Az idézõjelben levõ és az idézõjelek nélküli stringet a shell egyaránt kielemzi abból a szempontból, hogy kell-e helyettesítenie egy shell változó értéket, azaz a változónév behelyettesítése ellen a dupla idézõjel nem véd.

A kapcsos zárójel jelezte a shell változó nevének a határait. Ha nem használjuk, egyes esetekben, hasonló nevû shell változók eseten kétértelmû lenne a változónév kiértékelése.
 

4. Hogyan lehet a képernyõteírni azt, hogy

  A $HOME erteke ...

$ echo "A \$HOME erteke: $HOME
$ echo A '$HOME' erteke: $HOME

A \ jel vagy az ' jel feloldja a $ speciális jelentését.
 
 

UTASÍTÁSOK
 
 

A for utasítás formája a következõ:

  for name in word_list do command_list done

ahol a word_list egy karakterláncokból álló felsorolás. A for utasítás végrehajtásakor a shell a name változónak sorra a word_list felsorolásban szereplõ értékeket adja, s ezzel az értékkel hajtja végre a command_list parancssorozatot.

Ha az in word_list rész hiányzik a for ciklus megadásakor, akkor a word_list értéket a shell automatikusan $* -nak értelmezi.
 

Példák:


1. Írjuk ki az a1, a2 és a3 állományok nevét es tartalmát.

$ cat >ir1
  for i in a1 a2 a3; do
    echo Az allomany neve: $i
    echo Az allomany tartalma:
    cat $i
  done
CTRL-D
$ chmod +x ir1 $ ir1

 

2. Írjuk ki a parancssoban megadott állományok nevét es tartalmát.

$ cat >ir1
  for i; do
    echo Az allomany neve: $i
    echo Az allomany tartalma:
    cat $i
  done
CTRL-D
$ chmod +x ir1 $ ir1



A shift utasítás formája:

  shift [n]

A $n+1 $n+2 ... pozicionális változókat átnevezi $1 $2 ... -re. Ha n nincs megadva, akkor értéke 1.
 
 

Példa.
 

$ cat >shift1
  for i; do echo $i; done
  echo "shift"
  shift
  for i; do echo $i; done
CTRL-D
$ chmod +x shift1
$ shift1 A B C D
  A
  B
  C
  D
  shift
  B
  C
  D
$ cat >shift2
  for i; do echo $i; done
  echo "shift"
  shift 2
  for i; do echo $i; done
CTRL-D
$ chmod +x shift2
$ shift2 A B C D
  A
  B
  C
  D
  shift
  B
  C
$

 
 

A case elágazási mechanizmus:
 

  case word in case_part esac

ahol a case_part a következõ lehet:

  pattern) command_list;;
 

Az utasítássort 2 pontosvesszõ zárja.
 

Példa:

$ cat >szamok
  case $1 in
         0) echo nulla;;
         1) echo egy;;
         2) echo ketto;;
         3) echo harom;;
         4) echo negy;;
         5) echo ot;;
         6) echo hat;;
         7) echo het;;
         8) echo nyolc;;
         9) echo kilenc;;
     nulla) echo 0;;
       egy) echo 1;;
     ketto) echo 2;;
     harom) echo 3;;
      negy) echo 4;;
        ot) echo 5;;
       hat) echo 6;;
       het) echo 7;;
     nyolc) echo 8;;
    kilenc) echo 9;;
  esac
CTRL-D
$ szamok 3
  harom
$ szamok hat
  6
$


A && rövidítés azt jelenti, hogy a parancssor következõ parancsa csak akkor fut le, ha az elõzõ parancs visszatérési értéke igaz volt. (0 exit status).

A || rövidítés azt jelenti, hogy a parancssor következõ parancsa csak akkor fut le, ha az elõzõ parancs visszatérési értéke hamis volt.
 

Példa:

Cseréljük ki két állomány nevét:

$ cat >exch
  TMP="temp$$"
  mv $1 $TMP && mv $2 $1 && mv $TMP $2
CTRL-D
$ exch a1 a2

Mivel a PID értékek egyediek, a $$ segítségével egyedi fájlneveket generálhatunk.


EXIT STATUS

A parancsok végrehajtásának sikerességérôl informál. Sok Unix parancs, de nem mindegyik, állítja be ezt az értéket, amit a shellben a ? változó $? alakú lekérdezésével tudunk meg. Általában a sikeresen lefutott parancs 0-ra állítja, ellenkezô esetben egy ettôl elterô értékre. Ha egy parancs nem állítja a visszatér&eacutelsi változó értéket, akkor a legutolsó beállítás marad érvényben.

Példa:

$ pwd
  /home/h123456
$ echo $?
  0
$ pwdd #feltetelezem, hogy nincs pwdd nevu futtathato allomany
  sh: pwdd: command not found
$ echo $?
  1


ELÁGAZÁSOK
 

Az if szerkezet:
 

if command_list1;
  then command_list2;
  [elif command_list3; then command_list4 elif_part]
  [else command_list;]
fi

A command_list több parancsból is állhat, ezeket a pontosvesszõvel, a kerek zárójelekkel vagy a pipe segítségével csoportosíthatuk. Több parancs eseten az utolsó parancs visszatérési kódja számit.
 
 

Példa.
 

$ if date | grep Apr; then echo Tavasz van! fi
  Wed Apr 17 20:57:30 MET 1998
  Tavasz van!
$

 

A test parancs szintakszisa:

  test kifejezes

A teszt parancs segítségével értékeket, karaktersorokat hasonlíthatunk össze, valamint fájlok tulajdonságait vizsgálhatjuk. Ha az argumentumként megadott kifejezés logikai értéke igaz, akkor a visszatérési érték nulla, egyébként nem-nulla.

Numerikus értékek összehasonlításakor használható opciók:
  -eq, -ne : egyenlõ, nem egyenlõ
  -gt, -lt : nagyobb, kisebb
  -ge, -le : nagyobb vagy egyenlõ, kisebb vagy egyenlõ

Fájlokkal kapcsolatos opciók:
  -s : igaz, ha a fájl létezik és nem üres
  -f : igaz, ha a fájl létezik és reguláris állomány
  -d : igaz, ha a fájl létezik és könyvtár
  -x : igaz, ha a fájl létezik és végrehajtható
  -w : igaz, ha a fájl létezik és írható
  -r : igaz, ha a fájl létezik és olvasható

Sztringek összehasonlítása
  = != : a ket sztring egyenlõ illetve nem egyenlõ
  -z   : igaz, ha a sztring hossza zéró
  -n   : igaz, ha a sztring hossza nem zéró


Példák.

1.

$ cat >teszt1
  if test $# -le 5
  then echo Az argumentumok szama kisebb vagy egyenlo mint 5.
  else echo Az argumentumok szama nagyobb mint 5.
  fi
CTRL-D
$ chmod +x teszt1
$ teszt1 a1 a2 a3
  Az argumentumok szama kisebb vagy egyenlo mint 5.
$ teszt1 a1 a2 a3 a4 a5 a6 a7
  Az argumentumok szama nagyobb mint 5.
$


2. Írjunk programot, amelyik megvizsgálja, hogy létezik-e a parancsargumentumként megadott fájl, es ha nem, akkor hozzuk létre.

$ cat >teszt2
  if test ! -s $1
  then
    echo A(z) $1 nevu fajl nem letezik, vagy ures!
    ls -l >$1
  else
    echo A(z) $1 nevu fajl letezik!
  fi
CTRL-D
$ chmod +x teszt2
$ teszt2 a1
  A(z) a1 nevu fajl letezik!
$


3. A program írja ki a parancsargumentumait addig, amíg "end"-et nem talál.

$ cat >teszt3
  if test $# -eq 0
  then
    echo Hianyoznak az argumentumok!
    exit 1
  fi
  while test $1 != "end"
  do
    echo Az argumentum: $1
    shift
    if test $# -eq 0
    then
      echo A parancsargumentumok nem tartalmazzak az end-et.
      exit 1
    fi
  done
  echo Megtalaltam az end-et!
CTRL-D
$ chmod +x teszt3
$ teszt3 a1 a2 end a3
  Az argumentum: a1
  Az argumentum: a2
  Megtalaltam az end-et!
$ teszt3
  Hianyoznek az argumentumok!
$ teszt3 a1 a2 a3
  A parancsargumentumok nem tartalmazzak az end-et.
$


4.

$ cat >teszt4
  if test $# -gt 2 -a $# -lt 5
  then
  echo A parmeterek szama 3 vagy 4.
  fi
CTRL-D
$ chmod +x teszt3
$ teszt3 a1 a2 a3
  A parmeterek szama 3 vagy 4. $


A while és az until ciklusok formája:

  while command_list1 do commandlist_2 done

  until command_list1 do command_list2 done
 

Példák.

Írjuk ki a parancssoban megadott állományok nevét es tartalmát.

$ cat >ir2
  while test $# -gt 0; do
    echo Az allomany neve: $1
    echo Az allomany tartalma:
    cat $1
    shift
  done
CTRL-D
$


$ cat >ir2
  until test $# -eq 0; do
    echo Az allomany neve: $1
    echo Az allomany tartalma:
    cat $1
    shift
  done
CTRL-D
$




Az expr parancs szintakszisa:

  expr argumentumok

Az expr logikai vagy aritmetikai kifejezésekként kezeli az argumentumokat és kiértekeli azokat. Az eredményt a standard outputra küldi. Az egyes argumentumokat szóközökkel kell elválasztani, a metakaraktereket semlegesíteni kell.
A használható függvények:
  +  összeadás
  -  kivonás
  *  szorzás
  /  osztás
  %  maradékos osztás

Példák.

1. Írjunk shell scriptet, amelyik kiírja a 2 parancsargumentum összegét, különbségét és szorzatát.

$ cat >szamol
  if test $# -ne 2
  then
    echo A programnak pontosan 2 argumentuma kell legyen.
    exit 1
  fi
  SUM=`expr $1 + $2`
  DIFF=`expr $1 - $2`
  PROD=`expr $1 \* $2`
  echo \$1= $1
  echo \$2= $2
  echo $1 + $2 = $SUM
  echo $1 - $2 = $DIFF
  echo $1 \* $2 = $PROD
CTRL-D
$ chmod +x szamol
$ szamol 5 2
  5 + 2 = 7
  5 - 2 = 3
  5 * 2 = 10
$

2. Írjunk shell scriptet, aminek 2 paramétere van. A script számoljon el egyesével az elsõ paramétertõl a másodikig és közben írja ki a számokat.

$ cat >szamol1
  usage="szamol1 arg1 arg2"
  if test $# -ne 2
  then
    echo Tul sok vagy tul keves parameter!
    echo $usage
    exit 1
  fi
  if test $1 -gt $2
  then
    echo Az elso parameter kisebb kell legyen, mint a masodik.
    echo $usage
    exit 1
  fi
  x=$1
  while test $x -le $2
  do
    echo $x
    x=`expr $x + 1`
  done
CTRL-D
$ chmod +x szamol1
$ szamol1 5 2
  Az elso parameter kisebb kell legyen, mint a masodik.
  szamol1 arg1 arg2
$ szamol1 1
  Tul sok vagy tul keves parameter!
  szamol1 arg1 arg2
$ szamol 3 7
  3
  4
  5
  6
  7
$


3. Hány Anna nevû user van összesen és ezek közül hányan nincsenek bejelentkezve?

$ cat >felhasznalok
  x1=`cat /etc/passwd | grep Anna | wc -l`
  x2=`finger | grep Anna | wc -l`
  x3=`expr $x1 - $x2`
  echo x3
CTRL-D
$ chmod +x felhasznalok
$ felhasznalok
  20
$



4. Elsõfokú egyenlet megoldása.

$ cat >egyenlet
  usage="usage: egyenlet par1 par2"
  if test $# -lt 2
    then echo $usage
  fi
  if test $1 -eq 0
  then
    if test $2 -eq 0
    then
      echo "vegtelen sok megoldas van"
      exit 1
    else
      echo "nincs megoldas"
      exit 1
    fi
  fi
  x=`expr 0 - $2 / $1`
  echo x=$x
CTRL-D
$ chmod +x egyenlet
$ egyenlet 3 3
$ x=-1 $



FELADATOK
 

1. Írjuk ki a képernyõre, hogy

  date

Hogyan érhetõ el, hogy az echo a napi dátumot írja ki?
 

$ echo date
  date
$ echo "date"
  date
$ echo `date`
  1998. Marcius 26. Csutortok 11:51:27 MET
$ echo '`date`'      # az egyszeres ' elnyomja a ` hatasat
  `date`
$ echo "`date`"
  1998. Marcius 26. Csutortok 11:51:27 MET


 

2. Írjuk ki, hogy egy fel perc múlva milyen folyamatok futnak a gépen.

$ (sleep 30; ps)&
 
 

3. Írjuk ki és számoljuk meg, hogy egy script indítása után hány shell fut.

$ cat >shellek
  ps | grep sh >temp
  echo "A futo shellek szama: `cat temp | wc -l`"
  echo "A futo shellek az alabbiak:\n `cat temp`"
CTRL-D
$ chmod +x shellek
$ shellek

 
 

4. Nézzük meg, hogy egy bizonyos felhasználó dolgozik-e és fut-e a épp valamilyen folyamata.

$ cat >dolgozik
  if who | grep $1 >temp; then
    echo "$1 dolgozik"
    if ps -ef | grep $1; then
      echo "a folyamatok"
    fi
  else echo "$1 nem dolgozik."
  fi
CTRL-D
$ dolgozik h123456
  h123456 nem dolgozik.
$


 

5. Írjunk "ébresztõórát" ami minden egész órakor üzenetet küld a képernyõre.
 

$ cat >alarm1
  until date | grep ':00:' >temp/FONT>
  do
    sleep 30
  done
  echo Haho!
CTRL-D
$

 

6. Hozzunk létre egy sorsz nevû programot, ami az f1 fájl sorainak számozásával állítja elõ az f2 állományt.
 
 

$ cat >sorsz
  k=1
  while sor=`line`; do
    echo $k $sor
    k=`expr ${k} + 1`
  done
CTRL-D
$

 
 
 
 

7. Van-e egy bizonyos évben hétfõvel kezdõdõ hónap? Ha találunk ilyet, írjuk ki betûkkel a hónap nevét.

$ cat hetfo
  k=ures
  p=elso
  for i in 1 2 3 4 5 6 7 8 9 10 11 12; do
    if cal $i $1 | grep ' 6$' >temp
    then
      k=nemures
      ho=abc
      case $i in
        1) ho=januar;;
        2) ho=februar;;
        3) ho=marcius;;
        4) ho=aprilis;;
        5) ho=majus;;
        6) ho=junius;;
        7) ho=julius;;
        8) ho=augusztus;;
        9) ho=szeptember;;
        10) ho=oktober;;
        11) ho=november;;
        12) ho=december;;
      esac
    fi
    if test $k = 'nemures'; then
      if test $p = 'elso'; then
        echo Az $1 evben hetfovel kezdodik
        p=masod
      fi
      echo $ho
      k=ures
    fi
  done
  if test $p = 'elso'; then
    echo Az $1 evben nincs
  fi
CTR-D
$ chmod +x hetfo
$ hetfo 1993
  Az 1993 evben hetfovel kezdodik
    februar
    marcius
    november
$ hetfo 1998
    Az 1998 evben hetfovel kezdodik
    junius
$