Takaisin pääsivulle

Linuxin komentorivin perusteet

Lähes kaikista Linuxin peruskomennoista ja useimmista ohjelmista saa lisätietoja niiden man-sivuilta komennolla "man komennonnimi". Joillakin harvoilla ohjelmilla ei ole man-sivuja, mutta on kuitenkin info-sivut. Info-sivut saa avattua komennolla "info komennonnimi", tai jos pinfo on asennettu, komennolla "pinfo komennonnimi". Useimmat ohjelman tulostavat lyhyen ohjeen jos ne käynnistetään käyttäen vipua --help, siis esimerkiksi "man --help". Seuraavan luvun kuvausten tarkoitus ei ole suinkaan korvata ohjelmien man-sivuja, vaan antaa yleiskäsitys Linuxin yleisimpien komentorivityökalujen toiminnasta. Toivottavasti ne myös havainnollistavat komentojen toimintaa käytännössä.

Komentorivikomennot annetaan aina jollekin komentotulkille. Ilman komentotulkkia ei siis ole komentoriviäkään. Linuxissa oletuskomentotulkki on yleensä bash, eikä toisen komentotulkin (esim. csh, zsh, ksh) asentaminen ole normaalisisti välttämätöntä. On kuitenkin syytä pitää mielessä, etteivät komentotulkit tulkitse komentoja täysin samalla tavalla, ja kullakin on omat vahvuutensa ja heikkoutensa. Erityisesti skriptejä kirjoitettaessa komentotulkkien erot tulevat ilmeisiksi. Pääosin komentoriviltä työnsä tekevälle eri komentotulkkien kokeileminen on varmasti vaivan arvoista: muille bash riittää vallan mainiosti.

HUOM: Kaikki allaolevat esimerkit on tehty bash-komentotulkin avulla.

Ohjelmien käynnistäminen komentoriviltä

Kaikki Linux-järjestelmään asennetut graafiset ohjelmat käynnistyvät X-ikkunointijärjestelmässä myös komentoriviltä (esim. xterm) kirjoittamalla niiden nimi ja painamalla returnia. Järjestelmä etsii ohjelmia hakupolusta (engl. path), johon kuuluvat tavallisilla käyttäjillä ainakin /bin, /usr/bin ja /usr/local/bin. Polkuun voi lisätä muitakin hakemistoja, joita voivat olla esimerkiksi /opt/bin ja ~/bin. Viimeksimainitulla viitataan käyttäjän kotihakemistossa olevaan bin-hakemistoon.

Jos et vaikkapa tiedä varmasti, onko ohjelman nimi esimerkiksi "mozilla-firefox" vai "firefox", käynnistä terminaali, kirjoita siihen esim. "mozi" ja näpäytä pari kertaa TAB -näppäintä. Näet kaikki ohjelmat, jotka alkavat kyseisellä tekstillä. Samalla tavoin voit kirjoittaa vain "openoff" ja painaa TABia. Bash-komentotulkki täydentää tekstin muotoon "openoffice", mikä ko. niminen ohjelma on asennettu ja löytyy hakupolusta.

Kun käynnistetään ohjelmia komentoriviltä, jää komentorivi yleensä "lukkoon". Tämä johtuu siitä, että komentorivi odottaa ohjelman suorituksen loppumista, jonka jälkeen komentorivi vapautuu. Ongelma voidaan ratkaista lisäämällä komennon perään &, esimerkiksi siis "mozilla-firefox &". Näin ohjelma käynnistyy suoraan taustalle, eikä varaa komentoriviä. Katso lisätietoja kohdasta "Prosessien ja töiden hallinta"

Komentojen tulosteen uudelleenohjaus

Komentojen putkitus eli "piping" on yksi Unix-käyttöjärjestelmien vahvuuksia. Se tarkoittaa yhden komennon antaman tuloksen siirtämistä toisen komennon syötteeksi. Useimmat komennot ottavat vastaan standardisyötettä (standard input) ja syöttävät ulos standardiulostulon (standard output) kautta. Lisäksi virheistä ilmoitetaan virheulostulon välityksellä (standard error). Jotkin ohjelmat tulostavat virheensä standardiulostulon kautta sen sijaan, että käyttäisivät virheulostuloa, niinkuin pitäisi. Onneksi tällaiset ohjelmat ovat harvinaisia.

Perusputkitusta hallitaan kolmella perusmerkillä:

"|"	Siirtää edeltävän komennon tulosteen jälkimmäisen komennon syötteeksi
">"	Siirtää edeltävän komennon tulosteen tiedostoon
">>"	Lisää edeltävän komennon tulosteen tiedoston loppuun
"2>"	Siirtää edeltävän komennon virhetulosteen tiedostoon
"2>>" Lisää edeltävän komennon virhetulosteen tiedoston loppuun

Putkittaminen on luultavasti helpointa ymmärtää esimerkkien kautta:

ls -l | less

Näyttää pitkän listauksen hakemiston tiedostoista ja avaa sen Less-lukuohjelmaan.

cat teksti.txt >> toinenteksti.txt

Lisää tiedoston "teksti.txt" tiedoston "toinenteksti.txt" loppuun.

find /home/ -name "*.swx" > /home/matti/openofficedocs.log

Etsii kotihakemistoista kaikki OpenOffice -tekstitiedostot (.sxw) ja kirjoittaa niiden sijainnit "openofficedocs.log" -tiedostoon. On myös mahdollista ohjata sekä komennon tuloste että sen virhetuloste samaan paikkaan esimerkiksi seuraavasti:

grep "teksti" tiedosto.txt > /dev/null 2>&1

Ylläolevassa esimerkissä kaikki grep-komennon antama tuloste hävitetään tarkoituksellisesti eli lähetetään laitteelle /dev/null. Kun halutaan nähdä komennon antama tuloste, mutta samalla ohjata se esimerkiksi tiedostoon, voidaan käyttää komentoa tee:

root@localhost:/# ls
bin   cdrom  etc   lib         media  opt   root  srv  tmp  var
boot  dev    home  lost+found  mnt    proc  sbin  sys  usr  vmlinuz
root@localhost:/# du -mcs /var /tmp /bin|tee /tmp/disk_usage.txt
251     /var
1       /tmp
4       /bin
254     yhteensä
root@localhost:/# cat /tmp/disk_usage.txt
251     /var
1       /tmp
4       /bin
254     yhteensä
root@localhost:/#

Säännölliset lausekkeet

Säännöllisellä lausekkeella tarkoitaan sääntöä, jonka perusteella tekstisyötteestä valitaan jokin osa. Lausekkeet voivat olla hyvinkin joustavia, joten niiden avulla voidaan tehdä hyvinkin monimutkaisia hakuja. Säännöllisten lausekkeiden opettelussa suurena apuna voi olla esimerkiksi txt2regex-ohjelma, joka luo säännöllisen lausekkeen askel askeleelta käyttäjän toiveiden mukaisesti.

Säännöllisiä lausekkeita käytetään erityisesti tekstimuotoisen materiaalin suodatuksessa, käsittelyssä ja analysoinnissa. Niiden osaaminen ei ole tavallisesti välttämätöntä, mutta kun ne osaa, tehostavat ne erityisesti komentorivityöskentelyä. Esimerkiksi tiedon etsintä ja suodatus grep-ohjelmalla helpottuu, kun hallitsee säännöllisten lausekkeiden perusteet. Joissakin graafisissakin ohjelmissa on mahdollista hyödyntää säännöllisiä lausekkeita esim. tekstin syntaksikorostuksien luomiseen (kts. esim. HTML-editori bluefish).

Käytettäessä säännöllisiä lausekkeita komentoriviltä on syytä muistaa, että komentotulkki saattaa tulkita jotkin merkit omiksi erityismerkeikseen. Tästä syystä säännöllisten lausekkeiden erityismerkkien eteen pitää usein laittaa merkki "\", jottei komentotulkki tulkitse sitä omaksi erityismerkikseen. Osittain edellämainitusta syystä säännölliset lausekkeet on syytä testata perinpohjaisesti ennen käyttöönottoa, jotta vältytään odottamattomilta yllätyksiltä.

Säännöllisillä lausekkeilla käsitellään tekstiä rivi kerrallaan, joten kaksi merkkiä on erityisen tärkeitä:

^ Rivin alku
$ Rivin loppu

Alla hyvin yksinkertainen esimerkki grep-ohjelmaa käyttäen. Vipu "-x" ilmoittaa, että säännöllisen lausekkeen on täsmättävä koko riviin.

samuli@localhost:/tmp$ cat regexp.txt 
Tämä teksti on tehty
säännöllisten lausekkeiden
esittelemistä varten.
Tämän tekstin ei ole
tarkoitus ei ole olla
muulla tapaa hyödyllinen.
samuli@localhost:/tmp$ grep -x "^Tämä.*" regexp.txt 
Tämä teksti on tehty
Tämän tekstin ei ole
samuli@localhost:/tmp$ grep -x ".*olla$" regexp.txt 
tarkoitus ei ole olla
samuli@localhost:/tmp$

Esimerkissä käytetään kirjainyhdistelmää ".*", joka luetaan "Mikä tahansa kirjain miten monta kertaa tahansa". Merkki "." on eräs säännöllisten lausekkeiden erikoismerkeistä. Se vastaa mitä tahansa merkkiä. Merkki "*" kuuluu toistomerkkeihin, jotka kertovat montako kertaa sitä edeltävä merkki saa toistua.

HUOM: alla olevat erikoismerkit toimivat GNU-ohjelmistoissa (esim. grep ja sed). Ne eivät välttämättä toimi sellaisenaan kaikissa säännöllisiä lausekkeita käyttävissä ohjelmissa. Esimerkiksi Python-ohjelmointikielessä monet allaolevista merkinnöistä on korvattu muilla merkintätavoilla.

Yleisimmät erikoismerkit:

. Mikä tahansa merkki
[:alnum:] Mikä tahansa kirjain- tai numeromerkki
[:alpha:] Mikä tahansa kirjainmerkki
[:space:] Välilyönti
[:upper:] Mikä tahansa iso kirjain
[:lower:] Mikä tahansa pieni kirjain
[:digit:] Mikä tahansa numeromerkki
[^n] Mikä tahansa merkki paitsi n

Luettelot ja sarjat:

[qwerty] Mikä tahansa kirjaimista q,w,e,r,t tai y
[aiw1_%-] Mikä tahansa merkeistä a, i, w, 1, _, %, -
[0-9] Mikä tahansa numeromerkki
[a-f] Käytettävästä kielestä riippuen yleensä sama kuin [abcdef], mutta voi tarkoittaa myös samaa kuin [aAbBcCdDeEfF]

Toistomerkit:

? Edellinen merkki toistuu korkeintaan kerran
* Edellinen merkki ei toistu ollenkaan tai toistuu miten monta kertaa tahansa
+ Edellinen merkki toistuu yhden tai useamman kerran
{n} Edellinen merkki toistuu tasan n kertaa
{n,} Edellinen merkki toistuu n tai useamman kertaa
{n,m} Edellinen merkki toistuu vähintään n ja korkeintaan m kertaa

Jos toistomerkkiä ei ole, merkin tulee toistua tasan kerran. Näinollen esimerkiksi säännöllinen lauseke Järvinen täsmää ainoastaan tekstiin Järvinen, eikä mihinkään muuhun.

Muutamat esimerkit valaissevat parhaiten eri tapoja käyttää säännöllisiä lausekkeita.

samuli@localhost:/tmp$ cat regexp.txt 
Tämä teksti on tehty
säännöllisten lausekkeiden
esittelemistä varten.
Tämän tekstin ei ole
tarkoitus ei ole olla
muulla tapaa hyödyllinen.

Ensin etsitään ylläolevasta tekstistä kaikki rivit, jotka sisältävät tekstin "ark" missä tahansa kohtaa riviä:

samuli@localhost:/tmp$ grep -x ".*ark.*" regexp.txt 
tarkoitus ei ole olla

Seuraavaksi etsitään ne rivit, joissa rivin alussa on mikä tahansa kirjain, ja sitä seuraa kirjain "ä" kaksi kertaa:

samuli@localhost:/tmp$ grep -x "^.ä\{2\}.*" regexp.txt 
säännöllisten lausekkeiden

Seuraava lauseke täsmää vain riveihin, jotka eivät ala isolla "T"-kirjaimella:

samuli@localhost:/tmp$ grep -x "^[^T].*" regexp.txt 
säännöllisten lausekkeiden
esittelemistä varten.
tarkoitus ei ole olla
muulla tapaa hyödyllinen.

Seuraava lauseke täsmää vain riveihin, jotka eivät ala sanalla "Tämä"

samuli@localhost:/tmp$ grep -x "^[^Tämä].*" regexp.txt 

säännöllisten lausekkeiden
esittelemistä varten.
tarkoitus ei ole olla

Seuraavassa esimerkissä etsitään rivit, joista löytyy sana "ei" välilyöntien ympäröimänä eli omana sananaan:

samuli@localhost:/tmp$ grep -x ".*[[:space:]]ei[[:space:]].*" regexp.txt
Tämän tekstin ei ole
tarkoitus ei ole olla

Nyt etsitään rivit, jotka alkavat joko kirjaimella "m" tai "s":

samuli@localhost:/tmp$ grep -x "^[ms].*" regexp.txt 

säännöllisten lausekkeiden
muulla tapaa hyödyllinen.

Alla olevassa esimerkissä etsitään rivit, jotka täsmäävät seuraaviin ehtoihin:

samuli@localhost:/tmp$ grep -x ".ä\+[mn].*" regexp.txt 

Tämä teksti on tehty
säännöllisten lausekkeiden
Tämän tekstin ei ole

On kuitenkin syytä huomata, että edellinen lauseke olisi täsmännyt myös esimerkiksi tekstiin "Tääääääämä". Eräs varsin hyödyllinen käyttötarkoitus säännöllisille lausekkeille on tarkasti jäsenneltyjen tiedostojen (esim. ohjelmakoodi, ohjelmien asetustiedostot yms.) tarkistaminen muodollisten virheiden varalta. Alla esimerkki elävästä elämästä:

#!/bin/bash
# Skriptille annetaan argumentiksi tarkistettavan tiedoston
# nimi, esim. "skriptin_nimi tiedosto.txt"
#
# Säännöllinen lauseke olettaa tiedoston rakenteen olevan
# suunnilleen seuraavanlainen:
#
# muuttujan.nimi = "arvo"; // Kommentti
	
echo "Virheelliset rivit tiedossa "\"$1\"
grep -nv '^.*[[:space:]]=[[:space:]]".*";[[:space:]]//.*' $1