Esimene shelliskript
Selles peatükis teeme väga väikese esimese shelliskripti ja vaatame, mida tähendavad shebang, chmod +x, argumendid, if, for ja exit code.
Loogika
Shelliskript on lihtsalt tekstifail, kus on järjest käsud, mida shell käivitab.
Esimese skripti eesmärk ei ole veel teha midagi keerulist. Piisab sellest, kui saad kätte viis põhiasja:
- kuidas skript algab
- kuidas ta käivitatavaks teha
- kuidas talle argumente anda
- kuidas teha lihtne tingimus
- kuidas tagastada edu või viga
Kiirspikker
#!/usr/bin/env bashvalib Bashichmod +x fail.shteeb faili käivitatavaks$1tähendab esimest argumenti"$@"tähendab kõiki argumenteif ... fiteeb tingimusloogikafor ... do ... donekordab tegevustexit 0tähendab edu,exit 1tähendab viga
Käivita need käsud
mkdir -p skripti-naide
cd skripti-naide
cat > tervita.sh <<'EOF'
#!/usr/bin/env bash
if [ $# -eq 0 ]; then
echo "Kasuta: $0 nimi..." >&2
exit 1
fi
for nimi in "$@"; do
echo "Tere, $nimi!"
done
EOF
chmod +x tervita.sh
./tervita.sh Mari Jaan
./tervita.sh
echo $?
Skripti loomine heredoc-iga
Skripti ei pea alati kokku panema pika printf käsuga. Väga tavaline ja loetav viis on kasutada here-doc'i.
Näide:
cat > tere.sh <<'EOF'
#!/bin/sh
echo "Tere skriptist"
pwd
EOF
Selle loogika on:
cat > tere.shkirjutab väljundi failitere.sh<<'EOF'tähendab, et järgmised read lähevad faili kuni realeEOF- jutumärkides
EOFhoiab ära selle, et shell hakkaks neid ridu juba loomise hetkel ise laiendama
See on väga mugav, kui skript on juba mitmerealine.
sh skript.sh, bash skript.sh, zsh skript.sh ja ./skript.sh
See on üks kõige tähtsamaid erinevusi shelliskriptide juures.
Need käsud ei tähenda päris sama asja:
sh skript.sh
bash skript.sh
zsh skript.sh
./skript.sh
Praktiline loogika on:
sh skript.shkäsib fail sisu tõlgendada shellilshbash skript.shkäsib fail sisu tõlgendada Bashilzsh skript.shkäsib fail sisu tõlgendada Zsh-l./skript.shkasutab skripti shebang-rida
See tähendab väga tähtsat asja:
- kui käivitad
bash skript.sh, siis otsustab tõlgendaja sina käsureal - kui käivitad
./skript.sh, siis otsustab tõlgendaja skripti esimene rida
Seepärast ei ole shebang ainult "ilus esimene rida", vaid päris käitumise osa.
Väike võrdlusnäide
Loo kõigepealt väga lihtne skript:
cat > naide.sh <<'EOF'
#!/bin/sh
echo "shell: $0"
echo "pwd: $(pwd)"
EOF
Nüüd proovi:
sh naide.sh
bash naide.sh
zsh naide.sh
chmod +x naide.sh
./naide.sh
Kõik need võivad selle lihtsa skripti puhul töötada, sest skript kasutab väga tavalist ja ühilduvat süntaksit.
See on hea esimene õppetund:
- lihtne POSIX-laadne skript töötab sageli mitmes shellis
- keerulisemad Bashi või Zsh eripärad enam mitte
Millal sh ja millal bash
Hea rusikareegel on:
- kui skript kasutab ainult lihtsat ja laialt ühilduvat süntaksit, sobib
#!/bin/sh - kui skript kasutab Bashi erisusi, siis kasuta
#!/usr/bin/env bash
Näiteks Bashi-spetsiifiline on sageli:
[[ ... ]]- massiivid
- mõni mugavam parameetrilaiendus
Näide, mis töötab Bashis, aga mitte tingimata sh-s
cat > bash-only.sh <<'EOF'
#!/usr/bin/env bash
nimi="Mari"
if [[ $nimi == M* ]]; then
echo "See on Bashi [[ ]] naide"
fi
EOF
Käivita:
bash bash-only.sh
chmod +x bash-only.sh
./bash-only.sh
Kui proovid sama käsuga:
sh bash-only.sh
siis võib see anda vea, sest sh ei pruugi Bashi süntaksit toetada.
Just siin tuleb shebang ja õige tõlgendaja valik päriselt mängu.
Shebang
Skripti esimene rida:
#!/usr/bin/env bash
ütleb, millise tõlgendiga see fail käivitada.
See on põhjus, miks sama tekstifail võib käituda skriptina, mitte lihtsalt tavalise tekstina.
Kui käivitad faili kujul:
./skript.sh
siis süsteem ei "arva niisama", et see on Bash või Zsh. Ta vaatab faili algust.
Kui esimene rida on näiteks:
#!/bin/sh
siis püütakse fail käivitada shelliga sh.
Kui esimene rida on:
#!/usr/bin/env perl
siis püütakse fail käivitada Perliga.
See tähendab:
- täitmisõigus ütleb, et faili tohib käivitada
- shebang ütleb, millega seda käivitada
Mõlemat on sageli vaja korraga.
Näide: sama idee teise tõlgendajaga
Skript ei pea olema ainult shelliskript. Sama loogika töötab ka teiste tõlgendatud keeltega.
Näide:
cat > tere.pl <<'EOF'
#!/usr/bin/env perl
print "Tere Perl-ist\n";
EOF
chmod +x tere.pl
./tere.pl
Siin:
- fail on tavaline tekstifail
- täitmisõigus lubab selle käivitada
- shebang ütleb süsteemile, et faili peab lugema Perl
Kui Perl puudub, siis ei saa faili käivitada, isegi kui chmod +x on tehtud.
chmod +x
Faili sisu üksi ei tee sellest veel käivitatavat skripti.
Selleks on vaja:
chmod +x tervita.sh
Pärast seda saad käivitada:
./tervita.sh Mari
Kui täitmisõigust ei ole, siis võid testi jaoks käivitada ka nii:
bash tervita.sh Mari
Või:
sh tervita.sh Mari
zsh tervita.sh Mari
Aga siis valid shelli sina käsureal, mitte skript ise shebang-reaga.
Argumendid
Kui kirjutad:
./tervita.sh Mari Jaan
siis:
$1onMari$2onJaan"$@"tähendab kõiki argumente koos
Esimese skripti juures on "$@" väga kasulik, sest saad ühe korraga läbi käia kõik antud nimed.
if
Selles skriptis on tingimus:
if [ $# -eq 0 ]; then
Selle mõte on:
- kui argumente ei antud
- siis näita kasutusjuhendit
- ja lõpeta veakoodiga
See on väga tavaline muster.
for
Tsükkel:
for nimi in "$@"; do
echo "Tere, $nimi!"
done
käib kõik argumendid ükshaaval läbi.
See on esimese skripti juures hea näide, sest seal on kohe näha, kuidas üks väike tööriist saab mitut sisendit töödelda.
Exit code
exit code on väga tähtis, sest see ütleb teistele programmidele ja shellile, kas töö õnnestus.
Tavaline rusikareegel:
0tähendab edu- muu arv tähendab viga
Selles skriptis:
- ilma argumentideta lõpetab ta
exit 1 - argumentidega lõpetab ta edukalt
Pärast käsu jooksutamist saad viimast koodi vaadata nii:
echo $?
Minitest
- Tee oma skript, mis tervitab ühte või mitut nime.
- Muuda see käivitatavaks.
- Käivita skript nii argumentidega kui ilma argumentideta.
- Vaata
echo $?abil, mis exit code jäi viimase käigu järel. - Seleta ühe lausega, mis roll on shebang'il.
- Loo üks skript here-doc'i abil kujul
cat > skript.sh <<'EOF'. - Proovi vahet
sh skript.shja./skript.shvahel.