Szántó Zsolt

honlapja
Tananyag:
Minden a /pub-ban!
Rodek Lajos jegyzet (zh-n is használható)
Rodek Lajos példák
pub példák (zh-n is használható) - /pub/OperaciosRendszerek/Nappali/Scriptek
Shell script írása Rodek Lajos jegyzet 72-73
#! /bin/bash

echo "Hello World!"
BASH scriptek futtatására a jegyzet 4 féle megoldást is említ a 73. oldalon. Nézzük meg, hogy mi a különbség az egyes módszerek között.
Futtasa le a jegyzetben szereplő 4 módszerrel az alábbi programot. A program a fájlrendszerben való pozíciónkat állítja át a /tmp-re. Vizsgálja meg, hogy mely esetben változott az aktuális shellünk pozíciója.
#! /bin/bash

cd /tmp

echo "Az alshell az alábbi mappába navigálódott:"
pwd
e
Változók használata Rodek Lajos jegyzet 76
#! /bin/bash

word="csoki"
echo "A $word finom."
#! /bin/bash

word="csoki"
echo "Szeretem a ${word}t."
Szövegek megadására használhatjuk az " (idézőjel) és ' (aposztróf) karaktereket. Ezekről részletesen a Rodek Lajos jegyzet 63. oldalán lehet olvasni.
#! /bin/bash

word="csoki"

echo "Idézőjelek használata (\"):"
echo "A $word finom."

echo "Aposztróf használata (\'):"
echo 'A $word finom.'

echo "Idézőjelek használata, a \\ segítségével a \$ jel nem speciális karakterként értelmeződik:"
echo "A \$word finom."
Parancssori paraméterek használata Rodek Lajos jegyzet 74-75
#! /bin/bash

echo "A $1 finom."
#! /bin/bash

echo "Az első 3 paraméter:"
echo $1 $2 $3

echo

echo "Az első 3 paraméter fordított sorrendben:"
echo $3 $2 $1
#! /bin/bash

echo "\$*, az összes parancssori pareméter: $*"
echo

echo "\$#, a paraméterek száma: $#"
echo

echo "\$0, A script neve és elérési útja: $0"
echo
#! /bin/bash

echo "\$*, az összes parancssori pareméter: $*"
echo

echo "\$#, a paraméterek száma: $#"
echo

echo "\$1, az első parancssori pareméter: $1"
echo

shift
echo "shift után:"
echo

echo "\$*, az összes parancssori pareméter: $*"
echo

echo "\$#, a paraméterek száma: $#"
echo

echo "\$1, az első parancssori pareméter: $1"
echo 
Parancs-behelyettesítés Rodek Lajos jegyzet 68
#! /bin/bash

sorok=$(cat $1 | wc -l)
echo "A sorok száma a $1 fájlban: $sorok"
Készítsen egy olyan programot, ami egy fájlt nem töröl közvetlenül, hanem azt lomtárba helyezi.
Jelenleg tételezzük fel, hogy a lomtár egy már korábban létrehozott mappa a /tmp/thrash címen.
A fájlnév a lomtárban legyen ugyanaz, mint ami az eredeti címen volt (azzal most még ne törödjünk, hogy mivan ha már volt ilyen nevű fájl a lomtárban).
(Ha még nem tetted meg, hozd létre a lomtárat a "mkdir /tmp/trash" paranccsal.)
#! /bin/bash

inFileName=`basename $1`
outFileName="/tmp/trash/$inFileName"

mv $1 $outFileName
#! /bin/bash

# Amennyiben nem adunk meg az célnál fájl nevet, csak mappa nevet, akkor a forrás fájl nevét fogja a célnál is használni.
mv $1 /tmp/trash/
Feltételes kifjezések - kilépési státus Rodek Lajos jegyzet 77-79
A test program a paraméterként megadott feltételes kifejezést értékeli ki, majd a kilépési státuszban jelzi annak logikai igazságértékét.
Kilépési státusz esetén a 0-t (hiba nélkül futott le a program) tekintjük igaznak, és minden mást hamisnak. (A $? az utoljára futatott program kilépési státuszát írja ki.)
#! /bin/bash

echo "A test program kilépési státuszai az alábbi kérdésekre:"

echo
echo "Létezik-e a /etc/passwd fájl?"
test -e /etc/passwd
echo $?

echo
echo "Létezik-e a /ilyenmappaugysincs/valami.txt fájl?"
test -e /ilyenmappaugysincs/valami
echo $?

echo
echo "Tudjuk-e olvasni a /etc/passwd fájl?"
test -r /etc/passwd
echo $?

echo
echo "A /etc/passwd egy közönséges fájl, amit tudunk olvasni?"
test -f /etc/passwd -a -r /etc/passwd
echo $?

echo
echo "3 kisebb-e, mint 4?"
test 3 -lt 4
echo $?

echo
echo "3 nagyob vagy egyenlő, mint 4?"
test 3 -ge 4
echo $?

echo
echo "Megegyező szövegek összehasonlítására"
test "szöveg" == "szöveg"
echo $?

echo
echo "Eltérő szövegek összehasonlítására"
test "szöveg" == "másik szöveg"
echo $?
A test helyett használhatjuk az alábbi jelölést is: [ feltétel ].
Itt a [ egy program, ami a teszttel azonosan működik, az egyetlen különbség, hogy utolsó paraméternek a ]-t várja.
#! /bin/bash

echo "A [ program kilépési státuszai az alábbi kérdésekre:"

echo
echo "Létezik-e a /etc/passwd fájl?"
[ -e /etc/passwd ]
echo $?

echo
echo "Létezik-e a /ilyenmappaugysincs/valami.txt fájl?"
[ -e /ilyenmappaugysincs/valami ]
echo $?

echo
echo "Tudjuk-e olvasni a /etc/passwd fájl?"
[ -r /etc/passwd ]
echo $?

echo
echo "A /etc/passwd egy közönséges fájl, amit tudunk olvasni?"
[ -f /etc/passwd -a -r /etc/passwd ]
echo $?

echo
echo "3 kisebb-e, mint 4?"
[ 3 -lt 4 ]
echo $?

echo
echo "3 nagyob vagy egyenlő, mint 4?"
[ 3 -ge 4 ]
echo $?

echo
echo "Megegyező szövegek összehasonlítására"
[ "szöveg" == "szöveg" ]
echo $?

echo
echo "Eltérő szövegek összehasonlítására"
[ "szöveg" == "másik szöveg" ]
echo $?
Feltételes kifjezések - if Rodek Lajos jegyzet 85
Az if a feltételnek megadott program kilépési státusza alapján dönti el, hogy az igaz vagy a hamis ágat használja.
Feltételben használhatjuk a test programot:
#! /bin/bash

if test -e $1
then
  echo "A $1 fájl létezik"
else
  echo "A $1 fájl nem létezik"
fi
A testtel ekvivalens módon a [-t.
#! /bin/bash

if [ -e $1 ]
then
  echo "A $1 fájl létezik"
else
  echo "A $1 fájl nem létezik"
fi
Vagy bármilyen másik tetszőleges program is megadható a feltételben.
#! /bin/bash

if mkdir /mnt/thrash 2> /dev/null
then
  echo "A /mnt/thrash könyvtár létre lett hozva"
else
  echo "A /mnt/thrash könyvtár már létezett"
fi
További példák:
#! /bin/bash

if [ $1 -lt $2 ]
then
  echo "$1 kisebb, mint $2"
elif [ $1 -eq $2 ]
then
  echo "A két szám megegyezik"
else
  echo "$1 nagyobb, mint $2"
fi
#! /bin/bash

if [ ! $# -eq 2 ]
then
  echo "A paraméterek száma nem megfelelő"
  exit 1
fi

if [ $1 -lt $2 ]
then
  echo "$1 kisebb, mint $2"
elif [ $1 -eq $2 ]
then
  echo "A két szám megegyezik"
else
  echo "$1 nagyobb, mint $2"
fi
Aritmetikai kifejezések Rodek Lajos jegyzet 80-81
#! /bin/bash

echo "2+4="
expr 2 + 4

echo
echo "2*5="
expr 2 \* 5

echo
echo "5/2="
expr 5 / 2

echo
echo "5%2="
expr 5 % 2

echo
echo "(5+10)*2="
expr \( 5 + 10 \) \* 2
#! /bin/bash

echo "2+4="
echo $((2+4))

echo
echo "2*5="
echo $((2*5))

echo
echo "5/2="
echo $((5/2))

echo
echo "5%2="
echo $((5%2))

echo
echo "(5+10)*2="
echo $(((5+10)*2))
Az aritmetikai kifejezések felhasználhatók feltételes kifejezésekben is.
#! /bin/bash

if (($1 < $2))
then
  echo "$1 kisebb, mint $2"
elif (($1 == $2))
then
  echo "A két szám megegyezik"
else
  echo "$1 nagyobb, mint $2"
fi
#! /bin/bash

for i in "csoki" "sör" "bor"
do
  echo "Szeretem a ${i}t"
done
#! /bin/bash

for i in $*
do
  echo $i
done
#! /bin/bash

for i in *
do
  echo $i
done
Feladatok
Készítsen egy olyan programot, ami a paraméterként kapott számok közül kiírja a párosakat.
#! /bin/bash

for i in $*
do
  mod=$((i % 2))
  if [ $mod -eq 0 ]
  then
    echo $i
  fi
done
#! /bin/bash

for i in $*
do
  if ((i % 2 == 0))
  then
    echo $i
  fi
done
Készítsen egy olyan programot, ami megadja a paraméterként kapott számok minimumát.
#! /bin/bash

min=$1

for i in $*
do
  if [ $i -lt $min ]
  then
    min=$i
  fi
done

echo "A paraméterek minimuma: $min"
Készítsen egy olyan programot, ami 3 paraméter vár, az első kettő egy-egy mappanév, a harmadik egy kiterjesztés. A program másolja át az első mappából a másodikba a megadott kiterjesztésű fájlokat.
#! /bin/bash

for i in $1/*.$3
do
  fileName=`basename $i`
  cp $1/$fileName $2/$fileName
done
#! /bin/bash

# A probléma egy cp-vel is megoldható
cp $1/*.$3 $2
Feladatok
Készítsen egy BASH scriptet, ami meghatározza a paraméterül kapott számok közül a legkisebb pozitív páros számot.
#! /bin/bash

min=2147483646
for i in $*
do
  if ((i>0 && i<min && i%2==0))
  then
    min=$i
  fi
done

echo $min
#! /bin/bash

min=2147483646
for i in $*
do
  if [ $i -gt 0 -a $i -lt $min -a $((i%2)) -eq 0 ]
  then
    min=$i
  fi
done

echo $min
Készítsen egy BASH scriptet, ami meghatározza, hogy az aktuális mappa közönséges fájljai közül melyik fájlban található a legtöbb sor.
#! /bin/bash

max=0
for i in *
do
  if [ -f $i ]
  then
    rows=$(cat $i | wc -l)
    if ((rows > max))
    then
      max=$rows
      maxFile=$i
    fi
  fi
done

echo "A legtöbb sor a(z) $maxFile fileban található, összesen $max"
Készítsen egy BASH scriptet, ami meghatározza, hogy egy adott mappa megadott kiterjesztésű fájlai közül melyikben szerepel a legtöbb sor. A programnak két paramétere legyen, az első a mappa elérési útvonala, a második a kiterjesztés.
#! /bin/bash

max=0
for i in $1/*.$2
do
  rows=$(cat $i | wc -l)
  if ((rows > max))
  then
    max=$rows
    maxFile=$i
  fi
done

echo "A legtöbb sor a(z) $maxFile fileban található, összesen $max"
Feladatunk a redundancia kiszűrése. Feltesszük, hogy az adott fájlokban minden sornak csak egyszer kell szerepelnie, így azokat a sorokat, amelyek már szerepeltek a fájlban korábban hívjuk fölöslegesnek. Készítsen egy programot, ami ami egy paramétert vár, egy fájl elérési útját. A program írja ki a képernyőre a fájlban szereplő fölösleges sorok számát, amennyiben nincs egyetlen fölösleges sor se, írja ki az alábbi üzenetet: "A fájlban nincsenek ismétlődő sorok".
#! /bin/bash

numberOfLines=`cat $1 | wc -l`
uniqNumberOfLines=`cat $1 | sort -u | wc -l`
repeatedLines=$((numberOfLines - uniqNumberOfLines))

if [ $repeatedLines -eq 0 ]
then
  echo "A fájlban nincsenek ismétlődő sorok"
else
  echo "Ismétlődő sorok száma: $repeatedLines"
fi
Késztsen egy BASH scriptet, ami egy paraméterként megadott mappában futtatási jogot ad az összes olyan .sh kiterjesztésű fájlhoz, amihez van olvasási jogunk.
#! /bin/bash

if [ $# -ne 1 ]
then
  echo "A program egy paramétert vár, ami a mappa elérési útja"
  exit
fi

for i in $1/*.sh
do
  if [ -r $i ]
  then
    chmod +x $i
  fi
done
Késztsen egy BASH scriptet, ami egy paraméterként megadott mappában futtatási jogot ad az összes olyan .sh kiterjesztésű fájlhoz, amihez van olvasási, de még nincs futtatási jogunk. A kimenetre írjuk ki, hogy hány fájl jogait módosítottuk.
#! /bin/bash

if [ $# -ne 1 ]
then
  echo "A program egy paramétert vár, ami mappa elérési útja"
  exit
fi

for i in $1/*.sh
do
  if [ -r $i -a ! -x $i ]
  then
    chmod +x $i
    ((++n))
  fi
done

echo "$n file lett módosítva"
Készítsen egy olyan programot, ami egy fájlt nem töröl közvetlenül, hanem azt lomtárba helyezi. A program használja lomtárnak a /tmp/trash mappát, ha még nem létezik, hozza létre. A program minimum 1, maximum 2 paramétert várjon. Az utolsó paraméter mindig a lomtárba helyezendő közönséges fájl elérési útja legyen. Két paraméter esetén az első egy opcionális kapcsoló: -f. Amennyiben a program nem megfelelően lett használva, írja ki az alábbi üzenetet:
"Használat: trash.sh [-f] file".
A script helyezze át a paraméterként megadott fájlt a lomtárba azonos néven. Ha a -f kapcsoló nincs megadva és létezett már a megadott néven fájl a lomtárban, akkor írja ki egy hibaüzenetet. Ha a -f kapcsoló megvan adva, akkor írja felül a lomtárban lévő fájlt.
#! /bin/bash

force="false"

if [ $# -eq 1 ]
then
  inFile=$1
elif [ $# -eq 2 -a "$1" == "-f" ]
then
  force="true"
  inFile=$2
else
  echo "Használat: trash.sh [-f] file"
  exit 1
fi

if [ ! -f $inFile ]
then
  echo "A(z) $inFile fájl nem létezik"
  exit 1
fi

if [ ! -e /tmp/trash ]
then
  mkdir /tmp/trash
  echo "A lomtár létre lett hozva"
fi

inFileName=`basename $inFile`
outFile="/tmp/trash/$inFileName"

if [ -f $outFile -a $force == "false" ]
then
  echo "A törlés sikertelen, létezik azonos nevű fájl a lomtárban, ha felül szeretné írni, használja a -f kapcsolót"
  exit 1
fi

mv $inFile $outFile
Készítsen egy BASH scriptet, ami egy mappa összes, megadott kiterjesztésű fájljáról statisztikát készít. A programnak két paramétert kell várnia, az első egy mappa ABSZOLÚT elérési útvonala, a második egy kiterjesztés. A program a megadott mappán belül hozzon létre egy fájlt, aminek a neve legyen a mappa_nev.stat alakú, ahol a mappa_nev a paraméterként megadott útvonalon található mappa neve. Az így kapott fájlba írjuk bele a mappában található összes megfelelő kiterjesztésű fájl nevét, méretét és típusát.
#! /bin/bash

dirName=$(basename $1)
outFileName="$1/$dirName.stat"

if [ -e $outFileName ]
then
  rm $outFileName
fi

for i in $1/*.$2
do
  fileName=$(basename $i)
  size=$(cat $i | wc -c)
  type=$(file $i)
  echo $fileName >> $outFileName
  echo "Méret: $size" >> $outFileName
  echo "Típus: $type" >> $outFileName
  echo >> $outFileName
done
Reguláris kifjezések - egrep Rodek Lajos jegyzet 88-93
Mappák kiszűrése az ls -l kimenetéből egrep segítségével.
ls -l | egrep "^d"
Olyan közönséges fájlok kiszűrése, amelyekre futtatási joga van a fájl tulajdonosának.
ls -l | egrep "^-..x"
Szűrjűk ki azokat a sorokat az email.txt fájlból, amelyek tartalmazzák az Internet vagy ARPANET szavak valamelyikét.
egrep "ARPANET|Internet" email.txt
Szűrjűk ki az 1970 és 2016 közötti évszámokat az email.txt fájlból.
egrep -o "19[7-9][0-9]|20(0[0-9]|1[0-6])" email.txt
Szűrjűk ki az e-mail címeket a data.txt fájlból. A példaben egy egyszerűsített szabályrendszert adunk meg e-mail címekre. (Az e-mail címek pontos leírásáról az alábbi linken olvashat.)
Az alábbi formátumú e-mail címeket szeretnénk felismerni: <local>@<subdomain>.<top-level domain>
Ahol a local rész legalább egy karakter hosszú kell, hogy legyen, és az alábbi elemekből épülhet fel:
  • Kisbetűk
  • Számok
  • Az alábbi karakterek: . _ -
A subdomain rész formátuma egyezen meg a local részével.
A top-level domain legalább 2 karakter hosszú legyen és csak kisbetűket tartalmazhat.
egrep -o "[a-z0-9._-]+@[a-z0-9._-]+\.[a-z]{2,}" data.txt
A feladat IPv4 címek kíszűrése. Az IPv4 címek 4 db 0 és 255 közötti számot tartalmaznak .-okkal elválasztva.

Elsőnek készítsünk egy egyszerűsetett szűrőt, amely 4 db maximum 3 jegyű .-okkal elválasztott számból álló sorozatot ismer fel.
egrep "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" data.txt
egrep "([0-9]{1,3}\.){3}[0-9]{1,3}" data.txt
Mostmár tényleg csak 0 és 255 közötti számokat engedjünk meg.
egrep "(2(5[0-5]|[0-4][0-9])|[01]?[0-9][0-9]?\.){3}(2(5[0-5]|[0-4][0-9])|[01]?[0-9][0-9]?)" data.txt
Az awk működése Rodek Lajos jegyzet 94-98
Utoljára 2015-ben módosított fájlok kiszűrése.
#! /usr/bin/awk -f
# Használat: ls -l | ./11_01_2015.awk

$8 == 2015 {
	print $8, $9
}
Mappák kiszűrése az ls -l kimenetéből awk segítségével.
#! /usr/bin/awk -f
# Használat: ls -l | ./11_02_folders.awk

$1 ~ /^d/ {
	print $1, $9
}
Awk beépített változók Rodek Lajos jegyzet 102-103
Az osztalyzatok.csv fájlból a programozás alapjai kurzusból 5-öst elért hallgatók kiszűrése.
#! /usr/bin/awk -f
# Használat: ./11_03_grades.awk osztalyzatok.csv

BEGIN {
	FS = ";"
}

$4 == 5 {
	print $1, $4
}
Minden második sor megjelenítése.
#! /usr/bin/awk -f
# Használat: ./11_04_even.awk osztalyzatok.csv

BEGIN {
	FS = ";"
}

NR % 2 == 0 {
	print NR, $0
}
Egyéb ajánlott irodalom

Követelmények
Részteljesítések, pontszerzési lehetõségek: 2 zárthelyi dolgozat, 5 db órai feladat.
  • Elsõ zárthelyi dolgozat: a 8-ik szorgalmi héten (március 21 - 24)
  • Második zárthelyi dolgozat: a 14-ik szorgalmi héten (május 2 - 5)
  • A zárthelyi dolgozat idõpontja elõre rögzített, nem változtatható, kizárólag indokolt esetben pótolható (megfelelõ igazolással).
  • A zárthelyi dolgozatokra 20-20, az órai kis feladatokra összesen 10 pontot lehet szerezni.
  • A zárthelyi feladatok megoldásához csak a helyszínen biztosított elektronikus segédanyag használható.
  • A zárthelyi dolgozatra szerezhetõ pontokon felül opcionális lehetõség van plusz pontok szerzésére órai feladatok megoldásával. Az órai feladatok közül az elsõ három az elsõ 7 szorgalmi hét gyakorlatain a többi kettõ a 9-ik szorgalmi héttõl 12-ik szorgalmi hétig lesznek kitûzve a gyakorlatokon
    • A feladatok kitûzésének idõpontjai nem lesznek elõre bejelentve
    • Mindegyik kis feladat helyes megoldása 2 pontot ér
      • részpontszám adható
    • A feladatok megoldása nem kötelezõ
    • A feladatokat egyénileg kell megoldani 10 perc alatt
    • A feladatok megoldásához használhatóak a /pub könyvtárban lévõ elektronikus anyagok
    • A megoldott feladatokat a gyakorlatvezetõk értékelik ki

A zárthelyi dolgozatok és az órai kis feladatok megoldására kapott pontok összege alapján történik a gyakorlati jegy megállapítása, de ennek összege nem lehet nagyobb a két zárthelyi dolgozatra szerezhetõ összpontszámnál:
0-19 pont: elégtelen (1)
20-24 pont: elégséges (2)
25-29 pont: közepes (3)
30-34 pont: jó (4)
35- pont: jeles (5)

Sikertelen gyakorlati teljesítés (elégtelen gyakorlati jegy) javítása javító zh megírásával lehetséges. Javító zh megírására az a hallgató jogosult, aki a szorgalmi idõszakbeli részteljesítései alapján elégtelen gyakorlati jegyet szerzett és mindkét zárthelyi dolgozatot megírta. A javító zh feladatai a teljes félév gyakorlati anyagát lefedik. A javító zh megoldásához csak a helyszínen biztosított elektronikus segédanyag használható. A javító zh-n 20 pont szerezhetõ. A javítás akkor sikeres, ha a hallgató a javító zh-n legalább 10 pontot szerez. Sikeres javítás esetén elégséges (2) gyakorlati jegy kerül megállapításra. Ennél jobb jegy még magasabb pontszám esetén sem adható. A javító zh megírására az 1. vizsgahéten, késõbb meghatározandó idõpontban kerül majd sor.