105.2 Lecke 2
Tanúsítvány: |
LPIC-1 |
---|---|
Verzió: |
5.0 |
Témakör: |
105 Shellek és shell scriptelés |
Fejezet: |
105.2 Egyszerű scriptek testre szabása vagy írása |
Lecke: |
2/2 |
Bevezetés
A shell scriptek általában arra szolgálnak, hogy automatizálják a fájlokkal és mappákkal kapcsolatos műveleteket, ugyanazokat a műveleteket, amelyeket manuálisan a parancssorból is el lehet végezni. A shell scriptek lefedettsége azonban nem csak a felhasználói dokumentumokra korlátozódik, mivel a Linux operációs rendszer számos aspektusának konfigurálása és interakciója is script-fájlokon keresztül valósul meg.
A Bash shell számos hasznos beépített parancsot kínál shell scriptek írásához, de ezeknek a scripteknek a teljes ereje a Bash beépített parancsai és a Linux rendszerben elérhető számos parancssori segédprogram kombinációjában rejlik.
Kibővített tesztek
A Bash, mint scriptnyelv leginkább a fájlokkal való munkára összpontosít, így a Bash beépített test
parancsa számos opcióval rendelkezik a fájlrendszer objektumainak (lényegében fájloknak és mappáknak) a tulajdonságainak kiértékelésére. A fájlokra és mappákra fókuszáló tesztek hasznosak például annak ellenőrzésére, hogy egy adott feladat végrehajtásához szükséges fájlok és mappák jelen vannak-e és olvashatók-e. Ezután egy if feltételes szerkezettel társítva a megfelelő műveletsorozatot hajtjuk végre, ha a teszt sikeres.
A test
parancs kétféle szintaxissal értékelhet kifejezéseket: a tesztkifejezések megadhatók a test
parancs argumentumaként, vagy szögletes zárójelek közé helyezhetők, ahol a test
parancs implicit módon van megadva. Így a /etc
érvényes mappára vonatkozó tesztet írhatjuk test -d /etc
vagy [ -d /etc]
formában:
$ test -d /etc $ echo $? 0 $ [ -d /etc ] $ echo $? 0
Amint azt a $?
speciális változóban szereplő kilépési státuszkódok is megerősítik — a 0 érték azt jelenti, hogy a teszt sikeres volt --, mindkét formátum érvényes mappaként értékelte az /etc
-t. Feltételezve, hogy egy fájl vagy mappa elérési útvonalát a $VAR
változóban tároltuk, a következő kifejezések használhatók a test
argumentumaként vagy szögletes zárójelben:
-a "$VAR"
-
Kiértékelődik, ha a
VAR
-ban megadott elérési út létezik a fájlrendszerben, és az egy fájl. -b "$VAR"
-
Kiértékelődik, ha a
VAR
-ban megadott elérési útvonal egy speciális blokkfájl. -c "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal egy speciális karakteres fájl. -d "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal egy mappa. -e "$VAR"
-
Kiértékelődik, ha a
VAR
-ban megadott elérési út létezik a fájlrendszerben. -f "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési út létezik, és az egy normál fájl. -g "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal rendelkezik-e SGID jogosultsággal. -h "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal szimbolikus hivatkozás. -L "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési út szimbolikus hivatkozás (mint a-h
-ban). -k "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő útvonal rendelkezik a sticky bit jogosultsággal. -p "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal pipe fájl. -r "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal olvasható az aktuális felhasználó számára. -s "$VAR"
-
Kiértékelődik, ha a
VAR
-ban lévő elérési út létezik, és nem üres. -S "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal egy socket fájl. -t "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal nyitva van egy terminálban. -u "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal rendelkezik SUID jogosultsággal. -w "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal írható az aktuális felhasználó számára. -x "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal az aktuális felhasználó által végrehajtható. -O "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő útvonal az aktuális felhasználó tulajdonában van. -G "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal az aktuális felhasználó effektív csoportjához tartozik. -N "$VAR"
-
Kiértékelődik, ha a
VAR
-ban szereplő elérési útvonal módosult a legutóbbi elérés óta. "$VAR1" -nt "$VAR2"
-
Kiértékelődik, ha a
VAR1
-ben lévő elérési útvonal újabb, mint aVAR2
-ben lévő elérési útvonal, a módosítási dátumok szerint."$VAR1" -ot "$VAR2"
-
Kiértékelődik, ha a
VAR1
-ben lévő elérési útvonal régebbi, mint aVAR2
. "$VAR1" -ef "$VAR2"
-
Ez a kifejezés True értéket ad, ha a
VAR1
-ben lévő elérési útvonal hardlink aVAR2
-hez.
A tesztelt változók körül azért ajánlott a kettős idézőjelek használata, mert ha a változó üres, az a test
parancsnál szintaktikai hibát okozhat. A tesztelési kapcsolóknak szükségük van egy operandus argumentumra, és egy idézőjel nélküli üres változó hibát okozna a szükséges argumentum hiánya miatt. Vannak tetszőleges szöveges változókra vonatkozó tesztek is, amelyeket az alábbiak szerint írunk le:
-z "$TXT"
-
Kiértékelődik, ha a
TXT
változó üres (nulla méretű). -n "$TXT"
vagytest "$TXT"
-
Kiértékelődik, ha a
TXT
változó nem üres. "$TXT1" = "$TXT2"
vagy"$TXT1" == "$TXT2"
-
Kiértékelődik, ha
TXT1
ésTXT2
egyenlőek. "$TXT1" != "$TXT2"
-
Kiértékelődik, ha
TXT1
ésTXT2
nem egyenlőek. "$TXT1" < "$TXT2"
-
Kiértékelődik, ha az
TXT1
azTXT2
előtt van, ábécé sorrendben. "$TXT1" > "$TXT2"
-
Kiértékelődik, ha az
TXT1
azTXT2
után következik, ábécé sorrendben.
Az egyes nyelvek eltérő szabályokkal rendelkezhetnek az ábécé sorrendre vonatkozóan. A konzisztens eredmények elérése érdekében, függetlenül attól, hogy milyen lokalizációs beállításokkal rendelkezik az a rendszer, ahol a scriptet végrehajtjuk, ajánlott a LANG
környezeti változót C
-re állítani, mint például a LANG=C
, mielőtt ábécé sorrendbe rendezéssel kapcsolatos műveleteket végeznénk. Ez a meghatározás a rendszerüzeneteket is az eredeti nyelven tartja, ezért csak a script hatókörén belül érdemes használni.
A numerikus összehasonlításoknak saját tesztelési módszereik vannak:
$NUM1 -lt $NUM2
-
Kiértékeli, ha`NUM1` kisebb, mint
NUM2
. $NUM1 -gt $NUM2
-
Kiértékelődik, ha
NUM1
nagyobb, mintNUM2
. $NUM1 -le $NUM2
-
Kiértékelődik, ha
NUM1
kisebb vagy egyenlő, mintNUM2
. $NUM1 -ge $NUM2
-
Kiértékelődik, ha
NUM1
nagyobb vagy egyenlő, mintNUM2
. $NUM1 -eq $NUM2
-
Kiértékelődik, ha
NUM1
egyenlőNUM2
-vel. $NUM1 -ne $NUM2
-
Kiértékelődik, ha
NUM1
nem egyenlőNUM2
-vel.
Minden teszt a következő módosítókat kaphatja:
! EXPR
-
Kiértékelődik, ha
EXPR
kifejezés hamis. EXPR1 -a EXPR2
-
Kiértékelődik, ha az
EXPR1
és azEXPR2
kifejezés is igaz. EXPR1 -o EXPR2
-
Kiértékelődik, ha a két kifejezés közül legalább az egyik igaz.
Egy másik feltételes szerkezet, a case
, az if egy változatának tekinthető. A case
utasítás akkor hajtja végre a megadott parancsok listáját, ha egy megadott elem — például egy változó tartalma — megtalálható a csővezetékekkel (pipe) (a függőleges vonallal |
) elválasztott és )
-vel végződő elemek listájában. A következő mintascript azt mutatja be, hogy a case
szerkezet hogyan használható egy adott Linux-disztribúció megfelelő szoftvercsomagolási formátumának megadására:
#!/bin/bash DISTRO=$1 echo -n "Distribution $DISTRO uses " case "$DISTRO" in debian | ubuntu | mint) echo -n "the DEB" ;; centos | fedora | opensuse ) echo -n "the RPM" ;; *) echo -n "an unknown" ;; esac echo " package format."
A minták és a hozzájuk tartozó parancsok listáját a ;;
, ;&
vagy ;;&
jelekkel kell lezárni. Az utolsó minta, egy csillag, akkor fog megfelelni, ha előtte nem volt más megfelelő minta. Az esac
utasítás (case visszafelé) lezárja a case
szerkezetet. Feltételezve, hogy az előző mintascript neve script.sh
, és az opensuse
első argumentummal hajtjuk végre, a következő kimeneti eredményt kapjuk:
$ ./script.sh opensuse Distribution opensuse uses the RPM package format.
Tip
|
A Bash rendelkezik egy |
A keresett elem és a mintázatok átesnek a tilde kiterjesztésen, a paraméterek kiterjesztésén, a parancsok helyettesítésén és az aritmetikai kiterjesztésen. Ha a keresett elemet idézőjelekkel adjuk meg, akkor azok eltávolításra kerülnek, mielőtt a megfeleltetés megtörténne.
Loop szerkezetek (ciklusok)
A scripteket gyakran használják ismétlődő feladatok automatizálásának eszközeként, ugyanannak a parancskészletnek a végrehajtásával, amíg egy leállítási kritérium nem teljesül. A Bash három ciklus utasítással rendelkezik - a for
, az until
és a while
-, amelyek kissé eltérő cikluskonstrukciókhoz készültek.
A for
szerkezet végigmegy egy adott elemlistán - általában szavak, vagy más szóközzel elválasztott szövegszegmensek listáján - és minden egyes elemen ugyanazt a parancskészletet hajtja végre. Minden egyes iteráció előtt a for
utasítás az aktuális elemet hozzárendeli egy változóhoz, amelyet aztán a mellékelt parancsok használhatnak. A folyamat addig ismétlődik, amíg az elemek el nem fogynak. A for
konstrukció szintaxisa a következő:
for VARNAME in LIST do COMMANDS done
A VARNAME
egy tetszőleges shellváltozó neve, a LIST
pedig egy tetszőleges szeparált kifejezésekből álló sorozat. A lista elemeit szeparáló érvényes elválasztó karaktereket (delimiter karakterek) az IFS
környezeti változó határozza meg, amelyek alapértelmezés szerint a szóköz, tab és újsor karakterek. A végrehajtandó parancsok listáját a do
és done
utasítások határolják, így a parancsok annyi sort foglalhatnak el, amennyit csak szükséges.
A következő példában a for
parancs a megadott listából minden egyes elemet - számok sorozatát - a NUM
változóhoz rendeli, egyszerre egy-egy elemet:
#!/bin/bash for NUM in 1 1 2 3 5 8 13 do echo -n "$NUM is " if [ $(( $NUM % 2 )) -ne 0 ] then echo "odd." else echo "even." fi done
A példában egy beágyazott if
szerkezetet használunk egy aritmetikai kifejezéssel együtt annak kiértékelésére, hogy az aktuális NUM
változóban lévő szám páros (even) vagy páratlan(odd). Feltételezve, hogy az előző példascript neve script.sh
, és az aktuális mappában van, a következő kimenet keletkezik:
$ ./script.sh 1 is odd. 1 is odd. 2 is even. 3 is odd. 5 is odd. 8 is even. 13 is odd.
A Bash egy alternatív formátumot is támogat a for
szerkezetkhez, mégpedig a dupla zárójeles jelölést. Ez a jelölés hasonlít a C programozási nyelv for
utasítás szintaxisára, és különösen hasznos a tömbökkel való munkához:
#!/bin/bash SEQ=( 1 1 2 3 5 8 13 ) for (( IDX = 0; IDX < ${#SEQ[*]}; IDX++ )) do echo -n "${SEQ[$IDX]} is " if [ $(( ${SEQ[$IDX]} % 2 )) -ne 0 ] then echo "odd." else echo "even." fi done
Ez a mintascript pontosan ugyanazt a kimenetet fogja generálni, mint az előző példa. Azonban ahelyett, hogy a NUM
változót használná az egyes elemek tárolására, az IDX
változót használja a tömb aktuális indexének növekvő sorrendben történő követésére, 0-tól kezdve és folyamatosan hozzáadva, amíg az a SEQ
tömbben lévő elemek száma alatt van. Az aktuális elemet a tömbi pozíciójából a ${SEQ[$IDX]}
segítségével keressük ki.
Hasonló módon az until
szerkezet addig hajt végre egy parancssorozatot, amíg egy tesztparancs — mint maga a test
— 0 (sikeres) állapottal nem terminálódik. Például az előző példában szereplő ciklust az until
-lal a következőképpen lehet megvalósítani:
#!/bin/bash SEQ=( 1 1 2 3 5 8 13 ) IDX=0 until [ $IDX -eq ${#SEQ[*]} ] do echo -n "${SEQ[$IDX]} is " if [ $(( ${SEQ[$IDX]} % 2 )) -ne 0 ] then echo "odd." else echo "even." fi IDX=$(( $IDX + 1 )) done
Az until
szerkezetek több utasítást igényelhetnek, mint a for
szerkezetek, de alkalmasabbak lehetnek a test
kifejezések vagy bármely más parancs által megadott nem számszerű megállási feltételekhez. Fontos, hogy olyan műveleteket tartalmazzon, amelyek biztosítják az érvényes leállási kritériumot, például egy számlálóváltozó inkrementálását, különben a ciklus a végtelenségig futhat.
A while
utasítás hasonló az until
utasításhoz, de a while
akkor ismétli meg a parancsok sorát, ha a tesztparancs 0 (sikeres) állapottal zárul. Ezért az until [ $IDX -eq ${#SEQ[*]} ]
utasítás az előző példából egyenértékű a while [ $IDX -lt ${#SEQ[*]} ]
utasítással, mivel a ciklusnak addig kell ismétlődnie, amíg a tömb indexe kisebb, mint a tömbben lévő elemek száma.
Egy részletesebb példa
Képzeljük el, hogy egy felhasználó rendszeresen szinkronizálni szeretné fájljainak és mappáinak gyűjteményét egy másik tárolóeszközzel, amelyet a fájlrendszer egy tetszőleges csatlakoztatási pontjához csatoltak, egy teljes körű biztonsági mentési rendszer pedig túlzásnak tűnik. Mivel ezt a tevékenységet rendszeresen kell elvégezni, ezért ez egy jó alkalom arra, hogy egy shellscript segítségével automatizáljuk.
A feladat egyszerű: szinkronizáljunk minden listában szereplő fájlt és mappát az első script argumentumként megadott kiindulási mappából a második script argumentumként megadott célmappába. A lista elemeinek könnyebb hozzáadása vagy eltávolítása érdekében a listát egy különálló fájlban, a ~/.sync.list
fájlban tároljuk, soronként egy elemmel:
$ cat ~/.sync.list Documents To do Work Family Album .config .ssh .bash_profile .vimrc
A fájl fájlok és mappák keverékét tartalmazza, némelyiknek a nevében szóköz is van. Ez egy jó forgatókönyv a beépített mapfile
Bash parancs számára, amely elemzi az adott szöveges tartalmat, és létrehoz belőle egy tömbváltozót, minden egyes sort külön tömbelemként elhelyezve. A script-fájl neve sync.sh
lesz, és a következő scriptet tartalmazza:
#!/bin/bash set -ef # List of items to sync FILE=~/.sync.list # Origin directory FROM=$1 # Destination directory TO=$2 # Check if both directories are valid if [ ! -d "$FROM" -o ! -d "$TO" ] then echo Usage: echo "$0 <SOURCEDIR> <DESTDIR>" exit 1 fi # Create array from file mapfile -t LIST < $FILE # Sync items for (( IDX = 0; IDX < ${#LIST[*]}; IDX++ )) do echo -e "$FROM/${LIST[$IDX]} \u2192 $TO/${LIST[$IDX]}"; rsync -qa --delete "$FROM/${LIST[$IDX]}" "$TO"; done
A script első művelete az, hogy a set
paranccsal átdefiniál két shellparamétert: az -e
kapcsoló azonnal kilép a végrehajtásból, ha egy parancs nem nulla státusszal terminálódik, az -f
pedig kikapcsolja a fájlnév-globbingot. Mindkét opciót -ef
-ként lehet rövidíteni. Ez nem egy kötelező lépés, de segít csökkenteni a váratlan viselkedés valószínűségét.
A script-fájl tényleges alkalmazásorientált utasításai három részre oszthatók:
-
script paraméterek összegyűjtése és ellenőrzése
A
FILE
változó a másolandó elemek listáját tartalmazó fájl elérési útvonala:~/.sync.list
. AFROM
ésTO
változók a kiindulási és a cél útvonalak. Mivel ezt a két paramétert a felhasználó adja meg, egy egyszerű validációra van szükség, amit azif
szerkezet végez el: ha a kettő közül bármelyik nem érvényes mappa — a[ ! -d "$FROM" -o ! -d "$TO" ]
teszt alapján --, a script egy rövid üzenetet jelenít meg és 1-es kilépési státusszal fejeződik be. -
Fájlok és mappák listájának betöltése
Miután minden paramétert definiáltunk, a
mapfile -t LIST < $FILE
paranccsal létrehozunk egy tömböt, amely a másolandó elemek listáját tartalmazza. Amapfile
-t
kapcsolója minden sorból eltávolítja az újsor karaktert, mielőtt aLIST
tömbváltozóba felvenné a sorokat. AFILE
változóban megadott fájl —~/.sync.list
— tartalmát a bemeneti átirányítással olvassa be. -
Másolás végrehajtása és a felhasználó tájékoztatása
Egy
for
ciklus kettős zárójeles jelölést használva végigjárja az elemek tömbjét, azIDX
változó pedig nyomon követi az index növekedését. Aecho
parancs tájékoztatja a felhasználót minden egyes másolt elemről. A kimeneti üzenetben jelen van a jobb nyíl karaktert jelképező, kivédett (escape)\u2192
unicode karakter, ezért azecho
parancs-e
kapcsolóját kell használni. Azrsync
parancs szelektíven csak a módosított fájldarabokat másolja az eredetiből, ezért ajánlott a használata az ilyen feladatokhoz. Azrsync
-q
és-a
kapcsolók (összevonva-qa
), meggátolják azrsync
üzeneteket és aktiválják az archive módot, ahol minden fájl tulajdonsága megmarad. A--delete
kapcsoló hatására azrsync
törölni fog egy olyan elemet a célmappában, amely már nem létezik az eredetiben, ezért óvatosan kell használni.
Feltételezve, hogy a listában szereplő összes elem létezik a carol
felhasználó home mappájában, a /home/carol
-ban, és a /media/carol/backup
célmappa egy csatlakoztatott külső tárolóeszközre mutat, a sync.sh /home/carol /media/carol/backup
parancs a következő kimenetet fogja generálni:
$ sync.sh /home/carol /media/carol/backup /home/carol/Documents → /media/carol/backup/Documents /home/carol/"To do" → /media/carol/backup/"To do" /home/carol/Work → /media/carol/backup/Work /home/carol/"Family Album" → /media/carol/backup/"Family Album" /home/carol/.config → /media/carol/backup/.config /home/carol/.ssh → /media/carol/backup/.ssh /home/carol/.bash_profile → /media/carol/backup/.bash_profile /home/carol/.vimrc → /media/carol/backup/.vimrc
A példa azt is feltételezi, hogy a scriptet a root vagy a carol
felhasználó hajtja végre, mivel a legtöbb fájl más felhasználók számára olvashatatlan lenne. Ha a script.sh
nem a PATH
környezeti változóban szereplő mappában található, akkor a teljes elérési útvonalát kell megadnunk.
Gyakorló feladatok
-
Hogyan lehetne a
test
parancsot használni annak ellenőrzésére, hogy aFROM
változóban tárolt fájl elérési útvonala újabb-e, mint egy olyan fájlé, amelynek elérési útvonalát aTO
változó tárolja? -
A következő scriptnek egy 0-tól 9-ig terjedő számsort kellene kiírnia, de ehelyett végtelen mennyiségű 0-t ír ki. Mit kell tennünk, hogy a várt kimenetet kapjuk?
#!/bin/bash COUNTER=0 while [ $COUNTER -lt 10 ] do echo $COUNTER done
-
Tegyük fel, hogy egy felhasználó írt egy scriptet, amely a felhasználónevek rendezett listáját igényli. Az így kapott rendezett lista a következőképpen jelenik meg a számítógépén:
carol Dave emma Frank Grace henry
A kollégája számítógépén azonban ugyanez a lista a következőképpen van elrendezve:
Dave Frank Grace carol emma henry
Mi lehet a magyarázat a két rendezett lista közötti különbségekre?
Gondolkodtató feladatok
-
Hogyan lehetne a script összes parancssori argumentumát felhasználni egy Bash tömb inicializálására?
-
Miért van az, hogy a
test 1 > 2
parancs a megérzéseinkkel szemben igaznak értékelődik ki? -
Hogyan változtathatná meg egy felhasználó ideiglenesen az alapértelmezett mezőelválasztót csak újsor karakterre, miközben továbbra is képes marad az eredeti tartalom visszaállítására?
Összefoglalás
Ez a lecke mélyebben megvizsgálja a test
parancshoz elérhető teszteket, valamint más feltételes és ciklusszerkezeteket, amelyek a bonyolultabb shell scriptek írásához szükségesek. Egy egyszerű fájlszinkronizálási scriptet mutatunk be példaként a shell-scriptelésre. A lecke a következő lépéseket veszi át:
-
Kibővített tesztek a
if
éscase
feltételes szerkezetekhez. -
Shell loop szerkezetek:
for
,until
éswhile
. -
Tömbökön és paramétereken való iterálás.
A bemutatott parancsok és eljárások a következők voltak:
test
-
A parancshoz megadott elemek összehasonlítása.
if
-
A parancsfájlokban használt logikai szerkezet, amely valamit igaznak vagy hamisnak értékel, majd az eredmények alapján elágazik a parancs végrehajtása.
case
-
Több érték kiértékelése egyetlen változóval szemben. A scriptparancs végrehajtása ezután a
case
parancs eredményétől függően történik. for
-
Egy parancs végrehajtásának megismétlése egy adott kritérium alapján.
until
-
Egy parancs végrehajtásának megismétlése, amíg egy kifejezés értéke hamis nem lesz.
while
-
A parancs végrehajtásának megismétlése, amíg egy adott kifejezés igaznak értékelődik ki.
Válaszok a gyakorló feladatokra
-
Hogyan lehetne a
test
parancsot használni annak ellenőrzésére, hogy aFROM
változóban tárolt fájl elérési útvonala újabb-e, mint egy olyan fájlé, amelynek elérési útvonalát aTO
változó tárolja?A
test "$FROM" -nt "$TO"
parancs 0 státuszkódot ad vissza, ha aFROM
változóban lévő fájl újabb, mint aTO
változóban lévő fájl. -
A következő scriptnek egy 0-tól 9-ig terjedő számsort kellene kiírnia, de ehelyett végtelen mennyiségű 0-t ír ki. Mit kell tennünk, hogy a várt kimenetet kapjuk?
#!/bin/bash COUNTER=0 while [ $COUNTER -lt 10 ] do echo $COUNTER done
A
COUNTER
változó értékét növelni kell, ami egy aritmetikai kifejezésselCOUNTER=$(( $COUNTER + 1 ))
oldható meg, hogy végül elérjük a megállási kritériumot és a ciklus véget érjen. -
Tegyük fel, hogy egy felhasználó írt egy scriptet, amely a felhasználónevek rendezett listáját igényli. Az így kapott rendezett lista a következőképpen jelenik meg a számítógépén:
carol Dave emma Frank Grace henry
A kollégája számítógépén azonban ugyanez a lista a következőképpen van elrendezve:
Dave Frank Grace carol emma henry
Mi lehet a magyarázat a két rendezett lista közötti különbségekre?
A rendezés az aktuális rendszerváltozaton alapul. Az ellentmondások elkerülése érdekében a rendezési feladatokat úgy kell elvégezni, hogy a
LANG
környezeti változóC
-re van állítva.
Válaszok a gondolkodtató feladatokra
-
Hogyan lehetne a script összes parancssori argumentumát felhasználni egy Bash tömb inicializálására?
A
PARAMS=( $* )
vagyPARAMS=( "$@" )
parancsok létrehoznak egyPARAMS
nevű tömböt, benne az összes argumentummal. -
Miért van az, hogy a
test 1 > 2
parancs a megérzéseinkkel szemben igaznak értékelődik ki?A
>
operátor stringek tesztelésére van, nem számokéra. -
Hogyan változtathatná meg egy felhasználó ideiglenesen az alapértelmezett mezőelválasztót csak újsor karakterre, miközben továbbra is képes marad az eredeti tartalom visszaállítására?
Az
IFS
változó másolata egy másik változóban tárolható:OLDIFS=$IFS
. Ezután az új sorválasztó azIFS=$'\n'
-el definiálható, az IFS változó pedig azIFS=$OLDIFS
-el állítható vissza.