Ha szeretnéd felépíteni a kocka hitelességedet, tarts velünk a scriptelős sorozatunk második részében. Van néhány javításunk, néhány fejlesztésünk az előző heti scripthez és egy útmutatónk a ciklusokhoz a beavatatlanok számára.
A Datecp script átvizsgálva
A scriptelős sorozunk első részében csináltunk egy scriptet, ami átmásolt egy fájlt egy biztonsági mentés könyvtárba, miután hozzáfűzte a dátumot a fájlnév végéhez.
Samuel Dionne-Riel rámutatott a hozzászólásokban, hogy van egy sokkal jobb módja is a változóink meghívásának kezelésére.
A paraméterek szóközzel vannak elválasztva a bash shellben, akkor működnek, ha van egy szóköz az eredményezett kiterjesztett parancsban. A scriptedben a
cp $1 $2.$date_formatted
addig működik terv szerint, ameddig a kiterjesztett változókban nincsenek szóközök. Ha ezen a módon hívod meg a scriptedet: datecp "my old name" "my new name"
a kibővítés ezt a parancsot eredményezi: cp my new name my old name.the_date, ami igazából hat paraméterrel rendelkezik
.
Hogy megfelelően címezd meg a dolgot, a scripted utolsó sorának így kellene kinéznie:
cp "$1" "$2.$date_formatted"
Ahogy láthatod, scriptünk sorának megváltoztatása erről:
cp -iv $1 $2.$date_formatted
Erre:
cp -iv “$1” “$2”.$date_formatted
Megoldja ezt a problémát, amikor a scriptünket olyan fájlokon használjuk, amiknek szóközök vannak a nevükben. Samuel rámutatott arra is, hogy amikor kódokat másolunk és beillesztünk erről az oldalról (vagy az internetről általában), legyél biztos benne, hogy behelyettesíted a megfelelő gondolatjeleket és idézőjeleket a "nyomdailag jobb" változatokhoz, amik gyakran felcserélik őket. Mi is egyre többet teszünk azért, hogy a kódjaink jobban másolás/beillesztés barátak legyenek. ;-)
Egy másik hozzászóló, Myles Braithwaite, úgy döntött, hogy kibővíti a scriptünket, így a dátum a fájlkiterjesztés előtt jelenne meg. Így ehelyett:
tastyfile.mp3.07_14_11-12.34.56
Ezt kapnánk:
tastyfile.07_14_11-12.34.56.mp3
Ami egy kicsit több kényelmet eredményez a felhasználók többségének. A kódja elérhető a GitHub oldalán. Nézzük meg mit használ ahhoz, hogy kihúzza a fájlnevet.
date_formatted=$(date +%Y-%m-%d_%H.%M%S)
file_extension=$(echo “$1″|awk -F . ‘{print $NF}’)
file_name=$(basename $1 .$file_extension)
file_name=$(basename $1 .$file_extension)
cp -iv $1 $file_name-$date_formatted.$file_extension
Megváltoztattam a formázást egy kicsit, de láthatod, hogy Myles az első sorban adja meg a dátum funkcióját. A második sorban azonban az "echo" parancsot használja a script első paraméterével a fájl nevének kimenetéhez. A pipe parancsot használja, hogy fogja a kimenetet és bemenetként használja a következő részhez. A Pipe után Myles meghívja az "awk" parancsot, ami egy erőteljes mintakereső program. Az -F jelző használatával megmondja a parancsnak, hogy a következő karakter (a szóköz után) az, ami meghatározza a "mezőelválasztó"-t. Ebben az esetben az egy pont.
Most az awk egy "tastyfile.mp3" nevű fájlt lát, ahogy két mezőből tevődik össze: "tastyfile" és "mp3". Végül a ‘{print $NF}’ -et használja arra, hogy megjelenítse az utolsó mezőt. Abban az esetben, ha a fájlod több pontot tartalmaz - mivel az awk parancs több mezőt képes látni - csak az utolsót fogja megjeleníteni, ami a fájlkiterjesztés.
A harmadik sorban létrehoz egy új változót a fájl nevéhez és a "basename" parancsot használja, hogy meghívjon mindent, ami az 1$-ban van, kivéve a fájlkiterjesztés. A fájlkiterjesztés automatikusan hozzáadásra kerül a változó miatt, ami meghívja a második sort. Amit ez tenne az az, hogy fogja a
tastyfile.mp3 -at
és átváltoztatja erre
tastyfile
Azután az utolsó sorban Myles összerakja a parancsot, ami mindent a megfelelő sorrendben fog kiadni. Figyeld meg, hogy nincs hivatkozás a $2-re, a script második paraméterére. Ez az egyéni script a megnevezett fájlt az aktuális könyvtárba másolja át helyette. Remek munka Samuel és Myles!
Scriptek futtatása és a $PATH
Megemlítettük az alapvető cikkünkben azt is, hogy a scripteket alapvetően nem lehet parancsként meghívni. Azaz a script elérhetési útvonalára kell mutatnod ahhoz, hogy futtasd:
./script~/bin/script
De a scriptjeid ~/bin/-be helyezésével csak beírhatod a nevüket bárhonnan, hogy futtasd őket.
A hozzászólók rászántak némi időt arra, hogy megtárgyalják, hogy ez mennyire megfelelő, mivel egyik modern Linux disztró sem hozza létre azt a könyvtárat. Továbbá egyik sem adja hozzá alapból a $PATH változóhoz sem, ami ahhoz szükséges, hogy a scripteket parancsszerűen futtassuk. Kissé zavart voltam, mert miután ellenőriztem a $PATH változómat, a hozzászólóknak igazuk volt, de a scriptek meghívása így is működött számomra. Megtaláltam miért: Sok modern Linux disztró létrehoz egy speciális fájlt a felhasználó home könyvtárában – .profile.
A fájlt beolvassa a bash (amíg a .bash_profile fájl jelen van a felhasználó home könyvtárában) és az alján van egy részleg, ami hozzáadja a ~/bin/ mappát a $PATH változóhoz, ha az létezik. Így ez a rejtély megoldódott. A sorozat hátralévő részében folytatom a scripet ~/bin/-be helyezését, mert ezek felhasználói scriptet és futtathatóknak kell lenniük a felhasználók által és úgy tűnik, hogy nem igazából kell babrálnunk a $PATH változóval kézzel, hogy működőképessé tegyük a dolgokat.
Parancsok ismétlése ciklusokkal
Térjünk rá az egyik leghasznosabb eszközre a kocka arzenálból az ismétlődő feladatok kezeléséhez:
ciklusok. Ma a "for" ciklusokat fogjuk megtárgyalni.
Az alapvető vázlata egy for ciklusnak az alábbi:
for VARIABLE in LIST; do
command1
command2
…
commandn
done
A VARIABLE lehet bármilyen változó, habár leggyakrabban a kisbetűs "i"-t használják megegyezés szerint. A LIST az elemek listája; megadhatsz több elemet (szóközzel elválasztva őket), mutathatsz egy külső szöveges fájlra, használhatsz egy csillagot (*), hogy kijelölj bármilyen fájlt az aktuális könyvtárban. A parancsok megegyezés szerint vannak behúzva, így könnyebb látni a felépítést - ciklusokat helyezni ciklusokra (így ciklusozhatsz miközben ciklusozol).
Mivel a listák szóközt használnak határolójelként - azaz egy szóköz kifejez egy lépést a következő elemre a listában - fájlok, amik szóközöket tartalmaznak a nevükben, nem igazán barátságosak. Egyelőre ragaszkodjunk a szóközök nélküli fájlokkal való munkához. Kezdjük egy egyszerű scripttel, ami kilistázza a fájlok neveit az aktuális könyvtárban. Csinálj egy új "loopscript" nevű scriptet a ~/bin/ mappádban. Ha nem emlékszel, hogy hogyan kell ezt csinálni (beleértve a végrehajthatóként való megjelölést és a hash durrantós hack hozzáadását), nézd meg a bash scriptelés alapok cikkünket.
Írd bele az alábbi kódot:
for i in item1 item2 item3 item4 item5 item6; do
echo “$i”
done
Ha futtatod a scriptet, csak meg kellene kapnod azokat az elemeket kimenetként.
Eléggé egyszerű, ugye? Nézzük meg, hogy mi történik, ha megváltoztatjuk a dolgokat egy kicsit.
Változtasd meg a scripteted úgy, hogy ezt fejezze ki:
for i in *; do
echo “$i”
done
Amikor ezt a scriptet egy mappában futtatod, meg kellene kapnod a benne lévő fájlok listáját kimenetként.
Most cseréljük az echo parancsot valami hasznosabbra – mondjuk a zip parancsra.
Ugyanis fájlokat fogunk hozzáadni egy archívumhoz. Most pedig tegyünk néhány paramétert a keverékbe!
for i in $@; do
zip archive “$i”
done
Van itt valami új! A "$@" egy rövidítés a "$1 $2 $3...$n"-hez. Más szavakkal ez az általad megadott összes paraméter teljes listája. Most nézd meg mi történik, amikor futtatom ezt a scriptet néhány bemeneti fájllal.
Láthatod melyik fájlok vannak a mappámban. Futtattam a parancsot 6 paraméterrel és minden fájl hozzá lett adva egy "archive.zip" nevű zippelt archívumhoz. Könnyű, igaz?
A for ciklusok meglehetősen csodálatosak. Most már alkalmazni tudsz kötegelt funkciókat fájlok listáin. Például bemásolhatod a scripjeid összes paraméterét egy zippel archívumba, áthelyezheted az eredetiket egy másik mappába és automatikusan biztonságosan másolhatod a zip fájlt egy távoli számítógépre. Ha beállítod a kulcs fájlokat SSH-val, többé be sem kell írnod a jelszavadat és megmondhatod a scriptnek, hogy törölje a zip fájlt feltöltés után!
A for ciklusok használata megkönnyíti műveletek sokaságának elvégzését minden fájlon egy könyvtárban. Összerakhatod parancsok széles választékát és használhatsz paramétereket nagyon könnyedén, hogy létrehozz egy menet közbeni listát és ez csak a jéghegy csúcsa.
Bash scriptelők, van bármilyen javaslatotok? Csináltál egy hasznos scriptet, ami ciklusokat használ? Meg szeretnéd osztani a sorozattal kapcsolatos gondolataidat? Hagyj néhány hozzászólást és segíts ki más kezdő scriptelőket!
Felhasznált forrás: The Beginner's Guide to Shell Scripting 2: For Loops
Nincsenek megjegyzések:
Megjegyzés küldése