Ero sivun ”Bash-skriptaus” versioiden välillä
Siirry navigaatioon
Siirry hakuun
p
ei muokkausyhteenvetoa
pEi muokkausyhteenvetoa |
|||
(34 välissä olevaa versiota 16 käyttäjän tekeminä ei näytetä) | |||
Rivi 3: | Rivi 3: | ||
== Alkuun == | == Alkuun == | ||
Skripti aloitetaan rivillä | Skripti aloitetaan rivillä | ||
< | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
</ | </syntaxhighlight> | ||
Joka kertoo, että skripti suoritetaan käyttäen bashia riippumatta siitä, mitä komentotulkkia käyttäjä käyttää ajaessaan skriptin. Huomaa, että vaikka rivi alkaa #-merkillä, se ei ole kommentti. Muualla skriptissä #:llä alkavat rivit ovat kommentteja, eikä niitä huomioida. | Joka kertoo, että skripti suoritetaan käyttäen bashia riippumatta siitä, mitä komentotulkkia käyttäjä käyttää ajaessaan skriptin. Huomaa, että vaikka rivi alkaa #-merkillä, se ei ole kommentti. Muualla skriptissä #:llä alkavat rivit ovat kommentteja, eikä niitä huomioida. | ||
Rivi 12: | Rivi 12: | ||
=== Ensimmäinen skripti === | === Ensimmäinen skripti === | ||
Tehdään aluksi yksinkertainen skripti, joka esittelee muutamia perustoimintoja: | Tehdään aluksi yksinkertainen skripti, joka esittelee muutamia perustoimintoja: | ||
< | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | |||
echo "Hei, $(whoami), mitä kuuluu" | |||
echo "Olet hakemistossa $(pwd), tiedostolistaus:" | |||
ls | |||
</ | </syntaxhighlight> | ||
Kuten huomaat, skripteissä käytetään tavallisia komentorivikomentoja, jotka sitten suoritetaan järjestyksessä. Toisaalta kuten myöhemmin huomaamme, skriptit tarjoavat paljon enemmän mahdollisuuksia kuin pelkkä komentojen näpyttely konsoliin. | Kuten huomaat, skripteissä käytetään tavallisia komentorivikomentoja, jotka sitten suoritetaan järjestyksessä. Toisaalta kuten myöhemmin huomaamme, skriptit tarjoavat paljon enemmän mahdollisuuksia kuin pelkkä komentojen näpyttely konsoliin. | ||
Rivi 24: | Rivi 24: | ||
Olet hakemistossa /home/kayttaja/ohjelmointi/skriptit, tiedostolistaus: | Olet hakemistossa /home/kayttaja/ohjelmointi/skriptit, tiedostolistaus: | ||
eka.sh | eka.sh | ||
Esimerkistä nähdään heti muutama perusasia. Ensinnäkin toisella rivillä käytetään ohjelmaa [[whoami]], joka tulostaa käyttäjänimen. Kun ohjelma on | Esimerkistä nähdään heti muutama perusasia. Ensinnäkin toisella rivillä käytetään ohjelmaa [[whoami]], joka tulostaa käyttäjänimen. Kun ohjelma on $()-merkinnän sisällä, kyseiseen kohtaan "kopioidaan" ajetun ohjelman tuloste. | ||
Toisella rivillä käytetään muuttujaa. Muuttujien edessä on dollarimerkki ($), ja niitä voidaan tunkea vaikka merkkijonojen (jotka erotetaan lainausmerkillä) sisälle. Muuttujia käsitellään tarkemmin myöhemmin. Esimerkissä käyttämämme muuttuja <tt>$PWD</tt> on [[ympäristömuuttuja]], jonka arvona on aina se hakemisto, jossa käyttäjä on. Voit kokeilla tätä esimerkiksi kirjoittamalla komentoriville komennon <tt>echo $PWD</tt>. | Toisella rivillä käytetään muuttujaa. Muuttujien edessä on dollarimerkki ($), ja niitä voidaan tunkea vaikka merkkijonojen (jotka erotetaan lainausmerkillä) sisälle. Muuttujia käsitellään tarkemmin myöhemmin. Esimerkissä käyttämämme muuttuja <tt>$PWD</tt> on [[ympäristömuuttuja]], jonka arvona on aina se hakemisto, jossa käyttäjä on. Voit kokeilla tätä esimerkiksi kirjoittamalla komentoriville komennon <tt>echo $PWD</tt>. | ||
Viimeisellä rivillä ajetaan normaalisti komentoriviohjelma [[ls]]. Voit myös kokeilla korvata tämän rivin rivillä | Viimeisellä rivillä ajetaan normaalisti komentoriviohjelma [[ls]]. Voit myös kokeilla korvata tämän rivin rivillä | ||
< | <syntaxhighlight lang="bash"> | ||
echo "`ls`" | |||
</ | </syntaxhighlight> | ||
Merkintä $() voidaan kirjoittaa myös ``, kuten alla esimerkissä. Tällöin kuitenkaan ei voi käyttää sisäkkäisiä komentoja. | |||
Skripti voitaisiin myös kirjoittaa suoraan komentoriville muodossa | |||
< | <syntaxhighlight lang="bash"> | ||
echo "Hei, `whoami`, mitä kuuluu"; echo "Olet hakemistossa $PWD, tiedostolistaus:"; ls; | |||
</ | </syntaxhighlight> | ||
== Muuttujat == | == Muuttujat == | ||
Muuttujat määritellään syntaksilla | Muuttujat määritellään syntaksilla | ||
< | <syntaxhighlight lang="bash"> | ||
nimi=arvo | |||
</ | </syntaxhighlight> | ||
ja niihin viitataan laittamalla muuttujan eteen $ | ja niihin viitataan laittamalla muuttujan eteen $ | ||
< | <syntaxhighlight lang="bash"> | ||
$nimi | |||
</ | </syntaxhighlight> | ||
Siinä tapauksessa mikäli halutaan, että komennon tulos on muuttuja asetetaan muuttuja tyyliin: | |||
<syntaxhighlight lang="bash"> | |||
nimi=("komennon nimi ja parametrit") | |||
</syntaxhighlight> | |||
Tapauksia, joissa käyttäjän tarkoittama muuttuja on epäselvä, tulee käyttää aaltosulkuja muuttujan ympärillä | Tapauksia, joissa käyttäjän tarkoittama muuttuja on epäselvä, tulee käyttää aaltosulkuja muuttujan ympärillä | ||
< | <syntaxhighlight lang="bash"> | ||
${foo}bar | |||
</ | </syntaxhighlight> | ||
kun halutaan tulostaa teksti <tt>bar</tt> muuttujan <tt>foo</tt> jälkeen. | kun halutaan tulostaa teksti <tt>bar</tt> muuttujan <tt>foo</tt> jälkeen. | ||
Ensimmäisen skriptimme tapauksessa käytimme jo ympäristömuuttujaa $PWD echo:n kanssa. Tehdäänpä samantyyppinen skripti nyt käyttäen itse määrittelemäämme muuttujaa: | Ensimmäisen skriptimme tapauksessa käytimme jo ympäristömuuttujaa $PWD echo:n kanssa. Tehdäänpä samantyyppinen skripti nyt käyttäen itse määrittelemäämme muuttujaa: | ||
< | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | |||
HEI="Hei, `whoami`, mitä kuuluu?" | |||
echo $HEI | |||
</ | </syntaxhighlight> | ||
Kuten huomaat, kun muuttujaan sijoitetaan arvo, voidaan käyttää samoja "kikkoja" kuin muuallakin skriptissä, esimerkiksi tässä tapauksessa sijoitamme muuttujaan merkkijonon jonka sisällä on ohjelman <tt>whoami</tt> tuloste. | Kuten huomaat, kun muuttujaan sijoitetaan arvo, voidaan käyttää samoja "kikkoja" kuin muuallakin skriptissä, esimerkiksi tässä tapauksessa sijoitamme muuttujaan merkkijonon jonka sisällä on ohjelman <tt>whoami</tt> tuloste. | ||
Rivi 67: | Rivi 73: | ||
Lisäksi muuttujaan sijoitettavan arvon on oltava lainausmerkkien sisällä, jos siihen kuuluu välilyönti. Yksittäisen sanan tai numeron voi sijoittaa ilman lainausmerkkejä: | Lisäksi muuttujaan sijoitettavan arvon on oltava lainausmerkkien sisällä, jos siihen kuuluu välilyönti. Yksittäisen sanan tai numeron voi sijoittaa ilman lainausmerkkejä: | ||
< | <syntaxhighlight lang="bash"> | ||
numero=43 | |||
</ | </syntaxhighlight> | ||
== Ehtolauseet == | == Ehtolauseet == | ||
Ehdollisia rakenteita luodaan bashille if, then, else ja fi -avainsanoilla. Rakenteen syntaksi on seuraava: | Ehdollisia rakenteita luodaan bashille if, then, else ja fi -avainsanoilla. Rakenteen syntaksi on seuraava: | ||
< | <syntaxhighlight lang="bash"> | ||
if [ ehto ] | |||
then | |||
lauseita | lauseita | ||
elif [ toinen ehto ] | |||
then | |||
lauseita | lauseita | ||
else | |||
muita lauseita | muita lauseita | ||
fi | |||
</ | </syntaxhighlight> | ||
Ehdot merkitään hakasulkeiden sisään esimerkiksi seuraavalla tavalla | Ehdot merkitään hakasulkeiden sisään esimerkiksi seuraavalla tavalla | ||
< | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | |||
if [ $PWD = "/" ] | |||
then | |||
echo "Tämä skripti suoritetaan juurihakemistossa"; | |||
else | |||
echo "Skripti suoritetaan hakemistossa $PWD"; | |||
fi | |||
</ | </syntaxhighlight> | ||
=== Yhden rivin ehtolauseet === | |||
Lyhyiden skriptien kanssa. | |||
<syntaxhighlight lang="bash"> | |||
[ ehto ] && lauseita || [ toinen ehto ] && lauseita || muita lauseita | |||
[ $PWD = "/" ] && printf "\nTämä skripti suoritetaan juurihakemistossa\n" || printf "\nSkripti suoritetaan hakemistossa %s\n" "$PWD" | |||
</syntaxhighlight> | |||
Tässä käytetään vertailuoperaattoria =, joka on tosi, jos merkkijonot ovat samat. Muita vertailuoperaattoreita ovat | Tässä käytetään vertailuoperaattoria =, joka on tosi, jos merkkijonot ovat samat. Muita vertailuoperaattoreita ovat | ||
Rivi 103: | Rivi 117: | ||
|- | |- | ||
<!-- taulukko alkaa tästä --> | <!-- taulukko alkaa tästä --> | ||
| ! || Negaatio-operaattori, "Onko seuraava ehto epätosi?" | |||
|- | |||
| -n || Pituus ei ole 0 | | -n || Pituus ei ole 0 | ||
|- | |- | ||
Rivi 135: | Rivi 151: | ||
Esimerkiksi seuraavat ehdot ovat tosia | Esimerkiksi seuraavat ehdot ovat tosia | ||
< | <syntaxhighlight lang="bash"> | ||
[ 2 -lt 5 ] | |||
[ "moi" != "linux" ] | |||
[ 54 -ge 53 ] | |||
[ -f "/etc/fstab" ] | |||
</ | </syntaxhighlight> | ||
== Silmukat == | == Silmukat == | ||
Rivi 146: | Rivi 162: | ||
For-silmukka on näppärä monessa tapauksessa, tässä esimerkkinä hakemiston kaikkien tiedostojen läpikäynti. | For-silmukka on näppärä monessa tapauksessa, tässä esimerkkinä hakemiston kaikkien tiedostojen läpikäynti. | ||
< | <syntaxhighlight lang="bash"> | ||
for muuttuja in `ls` | |||
do | |||
echo $muuttuja | |||
done | |||
</ | </syntaxhighlight> | ||
Silmukassa suoritettavat rivit laitetaan siis sanojen <tt>do</tt> ja <tt>done</tt> väliin. Laskurimuuttujaan sijoitetaan vuorotellen <tt>in</tt>:n jälkeen olevat sanat, esimerkiksi tässä tapauksessa | Silmukassa suoritettavat rivit laitetaan siis sanojen <tt>do</tt> ja <tt>done</tt> väliin. Laskurimuuttujaan sijoitetaan vuorotellen <tt>in</tt>:n jälkeen olevat sanat, esimerkiksi tässä tapauksessa komennon [[ls]] tuloste (eli hakemistossa olevien tiedostojen nimet). Ohjelman tuloste voidaan merkitä myös seuraavasti: <tt>$(komento)</tt>. Jos silmukalla on käytävä läpi kaikki kokonaisluvut tietyltä väliltä, voi käyttää komentoa [[seq]], joka tulostaa kokonaisluvut väliltä 1-annettu parametri. Esimerkiksi | ||
< | <syntaxhighlight lang="bash"> | ||
echo "Lasketaan kymmeneen:" | |||
for luku in $(seq 10) | |||
do | |||
echo $luku | |||
done | |||
</ | </syntaxhighlight> | ||
Läpi käytävä joukko voidaan merkitä myös syntaksilla <tt>{alku..loppu}</tt>. Jos esimerkiksi halutaan käydä läpi kaikki merkit c-o, kokeile vaikka kirjoittaa | Läpi käytävä joukko voidaan merkitä myös syntaksilla <tt>{alku..loppu}</tt>. Jos esimerkiksi halutaan käydä läpi kaikki merkit c-o, kokeile vaikka kirjoittaa | ||
<syntaxhighlight lang="bash">for muuttuja in {c..o}; { echo -n "$muuttuja "; sleep 1;}</syntaxhighlight> | |||
=== While === | === While === | ||
While suorittaa lausekkeita niin kauan kuin ehto on tosi. Kun ehto on epätosi poistutaan loopista | While suorittaa lausekkeita niin kauan kuin ehto on tosi. Kun ehto on epätosi poistutaan loopista jolloin skriptin suoritus jatkuu seuraavalta loogiselta riviltä (while-lausekkeen jälkeiseltä riviltä). | ||
< | <syntaxhighlight lang="bash"> | ||
while [ ehto ] | |||
do | |||
lauseita | |||
done | |||
Esimerkki: | Esimerkki: | ||
while [ -f "testi" ] | |||
do | |||
echo "Tiedosto on olemassa." | |||
sleep 1 | |||
done | |||
</ | </syntaxhighlight> | ||
Edellä oleva skripti tarkistaa, onko samassa hakemistossa oleva tiedosto <tt>testi</tt> olemassa. Tätä jatketaan niin kauan kunnes tiedostoa ei enää ole. | Edellä oleva skripti tarkistaa, onko samassa hakemistossa oleva tiedosto <tt>testi</tt> olemassa. Tätä jatketaan niin kauan kunnes tiedostoa ei enää ole. | ||
=== Until === | === Until === | ||
Until on while:n vastakohta. Until-lauseke jatkaa suoritusta niin kauan kunnes ehto on tosi. | Until on while:n vastakohta. Until-lauseke jatkaa suoritusta niin kauan kunnes ehto on tosi. | ||
< | <syntaxhighlight lang="bash"> | ||
until [ ehto ] | |||
do | |||
lauseita | |||
done | |||
</ | </syntaxhighlight> | ||
== Funktiot == | == Funktiot == | ||
Kuten "oikeissa" ohjelmointikielissä, myös bash-skripteissä on mahdollista käyttää funktioita seuraavalla tavalla | Kuten "oikeissa" ohjelmointikielissä, myös bash-skripteissä on mahdollista käyttää funktioita seuraavalla tavalla | ||
< | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
function Käyttis { | function Käyttis { | ||
Rivi 200: | Rivi 218: | ||
Käyttis | Käyttis | ||
echo $os | echo $os | ||
</ | </syntaxhighlight> | ||
Tulostaisi "Linux". | Tulostaisi "Linux". | ||
Funktio määritellään siis syntaksilla | Funktio määritellään siis syntaksilla | ||
< | <syntaxhighlight lang="bash"> | ||
function Funktio { | function Funktio { | ||
#koodi | #koodi | ||
} | } | ||
</ | </syntaxhighlight> | ||
Jos halutaan skriptin toimivan myös [[Sh]]-komentotulkkia käytettäessä, funktion kanssa on käytettävä syntaksia | Jos halutaan skriptin toimivan myös [[Sh]]-komentotulkkia käytettäessä, funktion kanssa on käytettävä syntaksia | ||
< | <syntaxhighlight lang="bash"> | ||
Funktio() { ... } | Funktio() { ... } | ||
</ | </syntaxhighlight> | ||
Jos muuttujia ei funktiossa erikseen määritellä yksityisiksi, ne ovat julkisia. Eli kun esimerkkiskriptissämme muutimme muuttujan $os arvoa funktiossa, tämä muutos näkyi myös funktion ulkopuolella. Muuttuja voidaan määritellä yksityiseksi avainsanalla <tt>local</tt>: | Jos muuttujia ei funktiossa erikseen määritellä yksityisiksi, ne ovat julkisia. Eli kun esimerkkiskriptissämme muutimme muuttujan $os arvoa funktiossa, tämä muutos näkyi myös funktion ulkopuolella. Muuttuja voidaan määritellä yksityiseksi avainsanalla <tt>local</tt>: | ||
< | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
function Käyttis { | function Käyttis { | ||
Rivi 228: | Rivi 246: | ||
Käyttis | Käyttis | ||
echo $os | echo $os | ||
</ | </syntaxhighlight> | ||
Tulostaisi "Debian". | Tulostaisi "Debian". | ||
Rivi 250: | Rivi 268: | ||
Kaikista Linux-järjestelmistä löytyviä ohjelmia on listattu luokkaan [[:Luokka:Komentorivin perustyökalut|Komentorivin perustyökalut]]. Näitä ohjelmia kannattaa selailla. Komentoriviohjelmia on listattu käyttötarkoituksen mukaan myös artikkelissa [[komentorivikomennot]]. | Kaikista Linux-järjestelmistä löytyviä ohjelmia on listattu luokkaan [[:Luokka:Komentorivin perustyökalut|Komentorivin perustyökalut]]. Näitä ohjelmia kannattaa selailla. Komentoriviohjelmia on listattu käyttötarkoituksen mukaan myös artikkelissa [[komentorivikomennot]]. | ||
Esimerkkinä ladataan kaikki [[LinuCast]]-podcastin [[ogg]]-muotoiset jaksot käyttämällä jokaisesta järjestelmästä löytyviä peruskomentoja [[seq]] ja [[wget]]: | Esimerkkinä ladataan kaikki [[LinuCast]]-podcastin [[ogg]]-muotoiset jaksot käyttämällä jokaisesta järjestelmästä löytyviä peruskomentoja [[seq]] ja [[wget]]: | ||
#!/bin/bash | |||
(esimerkin sivusto on kuollut ja kuopattu, joten koodi ei toimi) | |||
<syntaxhighlight lang="bash"> | |||
#!/bin/bash | |||
# linucast.sh - LinuCast-podcastin latausskripti | |||
for i in `seq -f"%03g" 1 104` | |||
do | |||
wget -c "http://koskisuomi.pp.fi/linucast/LinuCast$i.ogg" | wget -c "http://koskisuomi.pp.fi/linucast/LinuCast$i.ogg" | ||
done | |||
</syntaxhighlight> | |||
Esimerkkiohjelma voidaan tallentaa vaikka nimelle <tt>linuxcast.sh</tt> ja sille voidaan antaa [[chmod|suoritusoikeudet]] komennolla | |||
chmod u+rx | chmod u+rx linucast.sh | ||
Tämän jälkeen komentojono ajettaisiin komennolla | |||
./linucast.sh | |||
*1 tarkoittaa että mistä numerosta aloitetaan | |||
*104 tarkoittaa kuinka monta jaksoa haetaan, lukua voi kasvattaa jaksojen lisääntyessä. | |||
Esimerkki ohjelmana 2. Ladataan kaikki Full Circle magazinen englanninkieliset pdf-tiedostot palvelimelta. Esimerkissä on käytetty Bash skriptaus koodeja joita löytyy esimerkiksi tältä sivulta. | |||
<syntaxhighlight lang="bash"> | |||
#!/bin/bash | |||
# issueLataaja.sh - Ubuntu-aiheisen verkkojulkaisu Full Circle:n artikkelilataaja, kerää ne kaikki! | |||
# Tyhjennetään ruutu | |||
clear | |||
# Haetaan kaikki Full Circlen artikkelit ensimmäisestä beta-julkaisusta (0) kaikkein uusimpaan asti. | |||
# Listataan julkaisut verkkosivulta, joista viimeisin tallennetaan muuttujaksi. | |||
viimeisin_julkaisu=$(curl -s https://fullcirclemagazine.org/downloads/ | grep -oP '(?<=Issue )[0-9]+' | tail -1); | |||
for luku in $(seq 0 $viimeisin_julkaisu) | |||
do | |||
FILE="issue"$luku"_en.pdf" | |||
# Tarkistetaan onko tiedosto jo olemassa, ennen kuin ladataan se. | |||
if [ -f $FILE ]; then | |||
echo " '$FILE' tiedosto on olemassa." | |||
else | |||
echo " '$FILE' tiedostoa ei ole olemassa. Ladataan se..." | |||
wget "https://dl.fullcirclemagazine.org/$FILE" | |||
# Pidetään 5 sekunnin tauko latausten välissä, mukana laskuri | |||
for (( i=5; i>0; i--)); do | |||
sleep 1 & | |||
printf "\b\b$i" | |||
wait | |||
done | |||
fi | |||
done | |||
echo "Lataus valmis" | |||
</syntaxhighlight> | |||
Esimerkkiohjelma voidaan tallentaa vaikka nimelle <tt>issueLataaja.sh</tt> ja sille voidaan antaa [[chmod|suoritusoikeudet]] komennolla | |||
chmod u+rx issueLataaja.sh | |||
Tämän jälkeen komentojono ajettaisiin komennolla | |||
./issueLataaja.sh | |||
== Katso myös == | == Katso myös == | ||
*[[Komentorivin perusteet]] | *[[Komentorivin perusteet]] | ||
*[[Komentorivivinkkejä]] | *[[Komentorivivinkkejä]] | ||
*[[ShellCheck]] on ohjelma, joka havaitsee kaikki [[sh]] ja [[bash]]-skriptien ongelmat ja antaa niille parannusehdotukset. | |||
==Aiheesta muualla== | ==Aiheesta muualla== | ||
*[ | *[https://tldp.org/LDP/abs/html/ Advanced Bash-Scripting Guide] - laaja englanninkielinen opas bash-skriptaukseen | ||
*[ | *[https://www.panix.com/~elflord/unix/bash-tute.html Pikaopas bash-skriptaukseen] (englanniksi) | ||
*[ | *[https://web.archive.org/web/20170610153335/https://gd.tuwien.ac.at/linuxcommand.org/writing_shell_scripts.php Writing shell scripts] - toinen laaja englanninkielinen opas bash-skriptaukseen - archive.org tallenne 10.6.2017 | ||
*[https://www.shellcheck.net/ ShellCheck] on www-ohjelma, joka havaitsee kaikki [[sh]] ja [[bash]]-skriptien ongelmat ja antaa niille parannusehdotukset. | |||
*[https://explainshell.com/ ExplainShell] on www-ohjelma, joka antaa ohjetekstin annetuille komennoille. | |||
*[https://mywiki.wooledge.org/BashPitfalls Bash Pitfalls] yleisimmät bash-skriptauksen sudenkuopat. | |||
[[Luokka:Komentorivi]] | [[Luokka:Komentorivi]] | ||
[[Luokka:Ohjeet]] | [[Luokka:Ohjeet]] |