Sormet syvemmälle

ITKA203 Käyttöjärjestelmät -kurssin Demo 2 keväällä 2015 ja 2016 ja 2017. "Superpikajatko interaktiivisen Unix-shellin käyttöön"

Paavo Nieminen, paavo.j.nieminen@jyu.fi

Jyväskylän yliopiston tietotekniikan laitos.

STATUS: Saa alkaa tehdä. Raportoikaa ongelmista heti, jos ilmenee. Palautustapaa ollaan speksaamassa

Contents

Mistä tässä harjoitteessa on kyse

Tämä materiaali syntyi keväällä 2014, ja sitä on pienin muutoksin käytetty sen jälkeen. Pieniä muokkauksia saatetaan tehdä kurssin aikana, jos ensimmäisten tekijöiden osalta ilmenee jotain yllättäviä ongelmia. Demo on hieman lyhempi kuin ensimmäinen, mutta se rakentuu vahvasti edellisen päälle. Kertaile tarvittaessa ja tee itselle lisämuistiinpanoja, jos tuntuu että tarvitset!

Tarkoitus on jatkaa ensimmäisen demon pohjalta interaktiivisen shellin, erityisesti bashin, tehokäyttöä muutamien elämää helpottavien niksien kautta. Tutustutaan kurssin luennoissa meneillään oleviin tai pian esille tuleviin asioihin käytännössä. Lisäksi hankitaan lisää kädentaitoja tutustumalla joihinkin näppäriin apuohjelmiin. Tutkitaan binääritiedostoja omin käsin heksavedoksina. Tehdään myös ensimmäinen, tässä vaiheessa vielä hyvin triviaali, skripti eli komentoriviohjelma.

Tämän demon voi vielä tehdä Jyväskylän yliopiston yleisillä suorakäyttökoneilla (jalava, halava). Pysyttele silloin varovaisesti ohjeen mukaisissa toiminnoissa. Kurssin puolivälin jälkeen tullaan käyttämään kurssin omaa testipalvelinta itka203-testi.it.jyu.fi, jossa voidaan leikkiä vapaammin ja muita käyttäjiä häiritsemättä, mutta hintana on mm. se että verkkolevyn kotihakemistoa ("U-asema") ei ole kytketty, koneella sijaitsevia tietoja ei varmuuskopioida ja palvelin saattaa lakata toimimasta kesken kaiken.

Harjoituksen tavoitteet:

  • Shellin ja pääteyhteyden käyttö sujuvoituu.
  • Kurssin käsitteet konkretisoituvat itse naputtelemiesi esimerkkien kautta nähtynä.
  • Teet ensimmäisen skriptin.

Muista ensimmäisen demon varoitukset! Ajattele ennen kuin kirjoitat, ja ajattele uudelleen ennen kuin painat enteriä. Muutenkin voi kerrata asioita ensimmäisestä superpikaintrosta.

Keväällä 2015 määriteltyjen osaamistavoitteiden osalta demon tehtyään opiskelija:

Osa 1: Pääteyhteys ja screen, rinnakkaiset shellit

Jatketaan siitä, mihin aiemmin jäätiin (kertaile, jos on epäselvää): Osaat ottaa ssh-yhteyden yliopiston Linux-palvelimeen ja ymmärrät antavasi Bourne Again Shell (bash) -nimiselle shellille tekstimuotoisia komentorivejä, jotka shell suorittaa melko läheisessä yhteistoiminnassa palvelimeen asennetun käyttöjärjestelmän kanssa. Valtaosa tästä tekstimuotoisesta rajapinnasta on määritelty POSIX-standardissa, mutta GNU/Linux -ympäristössä on käyttömukavuutta ja -tehokkuutta helpottavia laajennoksia, joita hyödynnämme myös.

Teaser: tekstieditointi ja rinnakkaiset ohjelmat hankalalla tavalla

Tämä lyhyt osuus tarjoaa katsauksen yhteen helppoon tekstieditoriohjelmaan, joka ainakin Linuxeista usein löytyy. Lisäksi saadaan yksi käyttäjän näkökulma prosessinhallinnan käsitteeseen, joka on keskeisimpiä, kun puhutaan nykyaikaisista käyttöjärjestelmistä.

Ota normaalisti pääteyhteys IT-palveluiden suorakäyttökoneelle. Komenna:

nano

Käynnistit juuri tekstieditorin nimeltä GNU nano. Sitä on aika helppo käyttää, mutta se ei ole kovin monipuolinen. Jatkossa, kun demoissa hiukan editoidaan ohjelmia ym., voi periaatteessa käyttää nanoa, vaikka monipuolisemman editorin käyttö on ehdottomasti suositeltavaa.

Kirjoita jotain.

Näppäile M-z eli jos yhteysohjelmassasi toimii Alt-näppäimen käyttö, niin oman koneen näppäily Alt-z tuottaa tuon. Jos ei toimi, niin paina ensin ESC ja sitten z. Pitäisi saada näkymään alalaidassa teksti "Suspend enabled" tai "Suspension käytössä", mikäli kieliasetukset ovat suomenkieliset.

Varmista, että haluttu teksti "Suspend enabled" tai "Suspension käytössä" ilmestyi ruutuun.

Näppäile Ctrl-z

Mitä tapahtui? Olet taas shellissä. Komenna:

ps

Näet, että nano-ohjelma on yhä päällä, mutta se on pysäytetty (suspended). Voit antaa komentoja shellissä ja käyttää muita ohjelmia. Kokeile vaikka vanha tuttu ls, joka listaa tiedostot. Pysäyttämäsi nano pysyy taustalla siinä tilassa, jossa sen pysäytit. Tämä siis on sitä käyttäjän näkökulmaa prosessinhallintaan, jonka teoriaa luennoilla aletaan käydä läpi viimeistään toisella kurssiviikolla.

Komenna:

fg

Nyt viimeisin pysäytetty ohjelma tuli taas "etualalle" eli "foreground".

Nano on aika itsensäselittävä ohjelma. Sen voi lopettaa kokonaan näppäilemällä Ctrl-x. Tämä kuten muut näppäinkomennot näkyvät jatkuvasti Nano-ikkunan alalaidassa muodossa ^X.

Jatkossa halutaan editoida ohjelmakoodia tekstieditorilla ja aika samanaikaisesti kokeilla, miten ohjelmakoodi toimii käytännössä. Editori ei siis voi olla koko ajan päällä samassa ikkunassa. Vaikka sen voi edellä kerrotuilla näppäilyillä laittaa väliaikaisesti odottelemaan, on olemassa paljon näppärämpi tapa, joka on syytä ottaa haltuun tosi pian eli just nyt!

Mikä on screen -ohjelma?

Useat "ikkunat" yhtäaikaa käynnissä olevien ohjelmien käyttöön ovat arkipäivää mikrotietokoneissa sekä myös tableteissa ja älypuhelimissa. Viimeksi mainittujen laitteiden pienellä näytöllä näkyy kerrallaan vain yksi ikkuna, mutta voidaan ajatella että muidenkin ohjelmien ikkunat ovat "alla" tallella, vaikkei niitä juuri nyt käytetä - sovellukset ovat käynnissä taustalla ja niiden välillä voidaan vaihtaa jonkinlaisen ikkunamanagerin avustuksella. Linux-pääteyhteyttäkin käytät mitä luultavimmin tavallisen ikkunan kautta, esimerkiksi mikroluokkaan tai kotikoneelle asennetun KiTTY-yhteysohjelman kautta. Useiden sovellusten käyttäminen yhtäaikaa on näppärää myös palvelinkoneella; esimerkiksi tekstin editoiminen yhdessä ikkunassa ja ohjelman ajaminen ja tulosten tarkastelu toisessa ikkunassa on järkevältä kuulostava toimintamalli. Pääteyhteyden rinnalle voisi toki avata toisen, ihan vain käynnistämällä KiTTYstä toinen instanssi ja ottamalla toinen rinnakkainen yhteys etäkoneeseen. Tässä demossa harjoitellaan kuitenkin toista tapaa saada aikaan eri ikkunoita tekstimuotoisen pääteyhteyden yli. Parhaana analogiana toimii varmaankin juuri tabletti/älypuhelin, jossa koko näytön täyttää yksi ohjelma, vaikka monia muitakin ohjelmia on päällä yhtäaikaa.

Apuohjelma nimeltä screen mahdollistaa yhdenaikaiset teksti-"ikkunat", joista yksi on kerrallaan näkyvillä pääteyhteyden konsolissa. Katso huvikseen manuaalisivua komentamalla:

man screen

Siitähän se lähtee:

Screen is a full-screen window manager that multiplexes a physical
terminal between several processes (typically interactive shells).
Each virtual terminal provides the functions of a DEC VT100
terminal ...

Manuaalissa mainittu DEC VT100 on Intelin prosessoriin perustuva terminaalilaite, joka tuotiin markkinoille ennen tämän demolapun kirjoittajaa. Nykyisetkin päätteet emuloivat kyseistä vehjettä kivasti ( http://fi.wikipedia.org/wiki/VT100 ). Asiaan. (Intertekstuaalinen viite tarkoituksellinen.)

Manuaali kertoo asian pidemmästi, mutta tässä on lyhyt suomenkielinen kiteytys: Screen on ohjelma, joka monistaa yhden pääteyhteyden "päällekkäisiksi ikkunoiksi", joista yhtä voi käytellä ja toisissa voi olla ohjelmia käynnissä "taustalla". Lisäksi screenin voi pyytää irrottautumaan (engl. detach) vanhempiprosessistaan, mikä tekee siitä erityisen miellyttävän apuvälineen etäkoneiden käyttöön: Käyttäjä voi kirjautua ulos etäkoneesta, mutta screen sekä kaikki sen avulla käynnistetyt ohjelmat voidaan jättää käyntiin palvelimelle. Tyypillinen käyttötarkoitus yliopiston opiskelijoiden ja henkilökunnan keskuudessa onkin silminnähden (useimpina kellonaikoina komennolla ps -ef todeten) IRC-keskusteluverkon käyttö siten, että keskustelijan asiakasohjelma on läsnä, vaikka itse henkilö ei olisi kirjautuneena palvelimelle. Jotkut näyttävät käyttävän myös tekstimuotoisia email-ohjelmia, joista etäkoneillemme on asennettu ainakin pine ja mutt.

Screenin käynnistäminen, irtauttaminen ja liittäminen

Jos sinulla ei vielä ole palvelimella käynnistettyä screeniä, ensimmäinen lähtee päälle oletusasetuksilla komentamalla:

screen

Komento sellaisenaan ilman argumentteja käynnistää aina uuden instanssin screenistä. Tyypilliseen käyttötarpeeseen yksikin riittää. Anna joku simppeli komento, jolla on tuloste. Esimerkiksi:

ls

Screeniä ohjataan kaksimerkkisillä ohjauskomennoilla, jotka oletusarvoisesti aloitetaan painamalla Ctrl-a ja jatketaan toisella näppäimellä. Screenin irrottaminen vanhempiprosessista tapahtuu näppäilyllä Ctrl-a d eli ensin painetaan Ctrl-a ja seuraavaksi d. Kokeile.

Tilanne pitäisi olla, että edellä käynnistetty screen-prosessi on yhä taustalla, irrallaan pyörimässä. Siihen voi kytkeytyä uudelleen (reattach) komennolla:

screen -r

Tyypillistä on laittaa toiseksi argumentiksi vielä -d (detach) jolloin screen osaa irrottautua toisesta pääteyhteydestä, jos se oli sellaiseen kytketty, esimerkiksi jos käytät palvelinta välillä kotikoneelta, välillä mikroluokasta ja välillä läppäristä tai älypuhelimesta käsin:

screen -d -r

Kokeile. Pitäisi päästä takaisin edelliseen näyttöön. Jos jostain syystä on päällä useita instansseja screenistä, sinulle näytetään lista kyseisten instanssien prosessi-ID:stä, joista pitää antaa argumenttina se, johon halutaan kytkeytyä.

Screenin lopettaminen

Koko screen lopettaa toimintansa silloin, kun sillä ei ole itsellään enää yhtään lapsiprosessia. Kokeile lopettaa screen kirjoittamalla screenin sisällä pyörivään shelliin:

exit

Nyt screenillä ei ollut enää mitään tehtävää, ja sen suoritus loppui. Seuraava komento ei siis löydä yhtään olemassa olevaa screen-instanssia irrotettavaksi edellisestä yhteydestä ja liitettäväksi siihen, jossa operoit:

screen -d -r

Saa kokeilla. Jatketaan kuitenkin harjoituksia tämän demon loppuun screenissä, joten käynnistä se uudelleen. Komennon osaat jo. Kertaa edeltä tarvittaessa!

Screenin käyttelyä

Manuaalissa luetellaan runsaasti screenin komentoriviargumentteja ja näppäinkomentoja. Tässä on peruskäytön kannalta tärkeimmät näppäinyhdistelmät poimittuna suoraan englanninkielisestä manuaalisivusta. Vapaat suomennokset ja toimintakuvaelma löytyvät alempana. Päällekkäisistä versioista voi valita jomman kumman; joissakin toiminnoissa on vain yksi vaihtoehto. Isoilla ja pienillä kirjaimilla on screenin käyttöliittymässä eroa:

C-a a       (meta)        Send the command character (C-a) to window. See escape command.

C-a c
C-a C-c     (screen)      Create a new window with a shell and switch to that window.

C-a d
C-a C-d     (detach)      Detach screen from this terminal.

C-a f
C-a C-f     (flow)        Toggle flow on, off or auto.

C-a n
C-a C-n     (next)        Switch to the next window.

C-a p
C-a C-p     (prev)        Switch to the previous window (opposite of C-a n).

C-a ?       (help)        Show key bindings.

C-a [
C-a C-[
C-a esc     (copy)        Enter copy/scrollback mode.

Komennoista Ctrl-a d (detach) tuli käsiteltyä ja kokeiltua jo aiemmin. Yleensä pääteyhteyssessio päättyy juuri screenistä irrottautumiseen tällä näppäilyllä ja yhteyden päättämiseen exit -komennolla. Seuraavassa selitetään muut komennot ohjeen kirjoittajan mielipiteen mukaisessa tärkeysjärjesteyksessä peruskäytön kannalta.

Näppäily Ctrl-a c luo uuden ikkunan aiempien päälle, ja käynnistää ikkunaan shellin. Päällimmäisenä olevaa ikkunaa voi vaihtaa luontijärjestyksessä seuraavaan (next) ja edelliseen (prev) näppäilyillä Ctrl-a n ja Ctrl-a p. Näppäilyllä Ctrl-a f vaihtuva Flow-tila (on/off/auto) vaikuttaa tiettyjen näppäinten tulkintatapaan - kurssin luennoilla käytetyssä sessiossa tila on off, ja se saattaa vaikuttaa siihen, miten erityisnäppäilyt vaikuttavat luentoesimerkeissä. Yhteensopivuuden varmistamiseksi voit itsekin asettaa oman screen-sessiosi flown off-tilaan.

Näyppäilyllä Ctrl-a esc pääsee selaamaan screenin tulostehistoriaa (lisäselvitys alempana). Näppäily Ctrl-a a syöttää päällimmäisessä ikkunassa olevalle prosessille todellisen Ctrl-a -painalluksen, jota sille ei muilla keinoin pysty screenin kautta syöttämään, koska screen nappaa sen omaan tarkoitukseensa. Näppäily Ctrl-a ? näyttää listan screenin osaamista näppäinyhdistelmistä, joita tässä selviytymisohjeessa ei ole tarvetta mainita. Manuaali kertoo enemmän ja Internet vielä enemmän.

Potentiaalisia kummallisuuksia

Screenin käytössä on seuraavanlaisia implikaatioita:

  • Screen emuloi yhden 1970-lukulaisen kuvaruudun kokoista terminaalinäyttöä. Tulostehistoria ei välity pääteyhteyden yli omaan terminaali-ikkunaasi, vaan ohi kiitäneet tulosteet on katsottava screenin omasta tulostepuskurista näppäilyllä Ctrl-a esc. Tulostepuskurin tarkastelusta pääsee pois näppäilemällä pelkästään Esc. Screenissä on myös oma sisäinen copy-paste leikepöytä, jonka käyttöä ei tässä käsitellä. Manuaali kertoo kaiken, mikäli kiinnostaa.
  • Ctrl-a on tyypillinen näppäily, jota tarvitaan esimerkiksi tekstieditoreissa ja shellin komentorivin muokkauksessa (joissa se yleensä siirtää kursorin rivin alkuun). Voi kestää aikansa tottua siihen, että täytyykin painaa kahta nappia Ctrl-a a. Jos tämä häiritsee, screenin voi kyllä säätää kuuntelemaan jotakin muuta näppäintä Ctrl-a:n sijasta, mutta tässä ei mennä nyt niin syvälle. Manuaali kertoo lisää kustomoinnista.
  • Flow control -moodi voi vaihtua päälle painalluksella Ctrl-a f myös vahingossa ja epähuomiossa, jolloin voi olla hetken hukassa, kun esim. Ctrl-c ei tee sitä mitä olettaa (vaikkapa emacs-tekstieditorissa). Tilanne on kyllä välittömästi korjattavissa vaihtamalla moodi pois päältä.
  • Tyypillisistä käyttötarkoituksista (idlaaminen IRCissä ym.) johtuen screen-ohjelmaa ei aina tule itse edes sammutettua ennen kuin palvelin käynnistetään uudelleen ylläpitosyistä; kohteliasta on kuitenkin olla jättämättä aivan täysin turhia screeneja auki - ovathan ne lapsiprosesseineen viemässä resursseja tuhansien käyttäjien yhteisestä palvelinkoneesta! Esim. tämän kurssin ajan on aivan OK pidellä itseään kurssin epävirallisella IRC-kanavalla ja tehdä rinnakkaisissa screen-ikkunoissa demoja.
  • Palvelinkoneet tulleevat käynnistymään uudelleen pari kertaa kurssin aikanakin, joten muista kuitenkin tallentaa esim. tekstieditorissa muutetut tiedot. Uudelleenkäynnistyksen jälkeen luonnollisesti täytyy oma screen käynnistää uudelleen, ja tallentamattomat tiedot ovat todennäköisesti hukkuneet.

Kokeile screenin käyttöä hieman, eli ikkunoiden luontia, ikkunoiden sulkeutumista shelliin kirjoitetulla exit -komennolla ja ikkunoiden välillä vaihtamista. Tämän demon palautustehtävä kirjoitetaan yhdessä screen-ikkunassa etäkoneeseen asennetulla tekstieditorilla, ja sitä kokeillaan toisessa screen-ikkunassa. Palautustiedoston muodosta tarkastaja voi päätellä, että olet käytellyt screeniä ja editoria toivotulla tavoin.

Screenin opettelu varhaisessa vaiheessa helpottaa toimintaasi jatkossa.

Osa 2: Jumppaa kurssin aihepiirissä; esitietoja

Nyt olet saanut haltuun varsin näppärän työkalun etäyhteyksien käyttöön. Kehitä taitojasi screenin kanssa myös jatkossa koko ajan. Otetaan vielä pari elämää helpottavaa kikkaa ensimmäisessä demossa nähtyjen lisäksi ihan vaan motivoivina esimerkkeinä; asiasta kiinnostuneet löytänevät lisää omatoimisesti Internetin tutoriaaleista.

Tehokkaampaa näppäilyä

Aiemmassa demossa tutustuit interaktiivisen bash-shellin komentorivin editointiin ja edellisten komentojen hakemiseen komentohistoriasta nuolinäppäimiä käyttäen sekä tiedostojen nimien täydentämiseen tabulaattorilla (muistele ja kertaa tarvittaessa). Pidemmän päälle voi olla hyödyllistä viedä "selkäytimeen" näppäinyhdistelmät, joilla saman voi tehdä siirtämättä käsiä nuolinäppäimille. Nämä samat näppäinyhdistelmät toimivat myös monissa tekstipohjaisissa sovellusohjelmissa, kuten joissakin tekstieditoreissa:

Ctrl-p   vastaa nuolta ylös ("p" == previous line)

Ctrl-n   vastaa nuolta alas ("n" == next line)

Ctrl-f   vastaa nuolta oikealle ("f" == forward)

Ctrl-b   vastaa nuolta vasemmalle ("b" == backward)

Ctrl-e   vastaa end-näppäintä ("e" == end)

Ctrl-a   vastaa home-näppäintä ("a" == ??)

HUOM: Screeniä käytettäessä Ctrl-a on oletuksena komentonäppäin, joten
varsinaisen Ctrl-a:n tuottaminen vaatii screenissä tuplanäppäilyn:
"Ctrl-a a" eli ensin Ctrl-a ja sitten erikseen a.

Näppäinyhdistelmät vaikuttaisivat periytyvän aiemmista käytänteistä aina 1960- ja 1970-luvuilta saakka. Tarkkaavaisten opiskelijoiden löytämiä linkkejä historiakatsauksiin näppäilyjen osalta:

Kun näitä lähdet kokeilemaan, huomaa, että viereisistä näppäimistä tapahtuu sitten jotain aivan muuta. Suurin osa niistä on erittäin hyödyllisiä toimenpiteitä tehokäyttäjälle, mutta saattavat joskus yllättää varomattoman näppäilijän, joka ei osu alunperin tarkoittamaansa näppäimeen. Tässä potentiaalisimpia yllätysten aiheuttajia:

Ctrl-c   tyypillisesti lopettaa käynnissä olevan ohjelman

Ctrl-z   tyypillisesti pysäyttää käynnissä olevan ohjelman
         (tätä kokeiltiin demon alussa nano-editorissa)

Ctrl-d   tyhjän rivin alussa painettuna lähettää hangup-viestin,
         jolloin mm. shell loppuu saman tien ikään kuin olisi
         kirjoitettu komento "exit".

         Eipähän jatkossa tule yllätyksenä, jos yhteys katkeaa tästä
         syystä saman tien, vahingossa tai tahallaan. "Lepääminen
         d-kirjaimen päällä", niin että tulee automaattisesti monta
         Ctrl-d -painallusta, aiheuttaapi kaikkien screenissä
         olevien shell-ikkunoiden sulkeutumisen yksi kerrallaan,
         viimeisen sulkeutuessa itse screen-ohjelman sulkeutumisen
         ja seuraavaksi vielä koko pääteyhteyden sulkeutumisen.

         Rivin keskellä painettuna poistaa osoittimen alla olevan
         kirjaimen ("d" == delete)

Ctrl-j   Sama kuin enter, ts. komento lähtee saman tien.. VARO, jne..

Ctrl-m   Myös sama kuin enter, ts. komento lähtee saman tien.. VARO, jne..

Ctrl-o   Myös sama kuin enter, ts. komento lähtee saman tien.. VARO, jne..

Ctrl-i   Sama kuin tabulaattori, eli voi käyttää tiedostonimien
         täydentämiseen

Ctrl-l   Eli ällä. Tyhjentää terminaalinäkymän kuten komento clear.
         ("l" == cLear(?))

Ctrl-s   Pysäyttää tekstien saapumisen käyttäjälle päin (terminaalin
         standardisisääntulo), ei vaikuta palvelimelle päin meneviin
         näppäilyihin. Voi siis vaikuttaa ikään kuin yhteys olisi
         "jumissa", vaikkei se oikeasti ole. ("s" == ?? ks. edellä
         mainittu opiskelijan löytämä linkki historiakatsaukseen)

Ctrl-q   Jatkaa tekstien näyttämistä käyttäjälle päin, eli "korjaa
         Ctrl-s:n aiheuttaman näennäisen 'jumittumisen'" ("q" == ??
         ks. edellä mainittu opiskelijan löytämä linkki
         historiakatsaukseen)

Komentorivin editointia tehostavat entisestään mm. seuraavat näppäilyt:

Ctrl-k   Leikkaa rivin lopun osoittimesta oikealle päin komentorivin
         omalle leikepöydälle ("k" == kill)

Ctrl-u   Leikkaa rivin alun osoittimesta vasemmalle päin komentorivin
         omalle leikepöydälle ("u" == ??)

         HUOM: Macissä vaikuttaisi toimivan eri tavoin: Ctrl-u
         leikkaa koko rivin leikepöydälle riippumatta kursorin
         sijainnista. Ilmoitelkaahan, jos huomaatte muitakin
         erilaisuuksia Mac-maailmassa.

Ctrl-y   Liittää pätkän takaisin komentorivin omalta leikepöydältä.
         ("y" == yank)

Erityisen tehokas tehokäyttönäppäin on lisäksi seuraava:

Ctr-r    Aktivoi ominaisuuden, jolla komentohistoriasta voi etsiä
         kauan sitten tehtyä komentoriviä, joka sisältää merkkejä.
         ("r" == reverse-search)

         Jos olet esim. 3 päivää sitten tehnyt jotain eksoottista,
         mikä nyt pitäisi toistaa, niin riittää muistaa muutama
         leimallinen pätkä kyseisestä komennosta.

Kokeile edellisiä ja koeta saada niistä hyödyllisimmät selkäytimeen. Vaaraa ei ole silloin, kun tiedät, että näppäilysi ei tule suorittamaan sellaista komentoa, joka tuhoaisi dataa poistamalla tiedostoja tai kirjoittamalla niiden päälle.

Turvallisin ympäristö epävarmoille näppäilijöille on halavan/jalavan sijasta ottaa pääteyhteys tätä kurssia varten perustettuun testipalvelimeen itka203-testi.it.jyu.fi - sinne syntyy ensimmäisen kirjautumisen yhteydessä täysin oma, erillinen kotihakemisto, jolla ei ole yhteyttä yleiseen verkkolevyyn, jossa tärkeät tiedostosi sijaitsevat. Kyseiselle testipalvelimelle ei kuitenkaan myöskään pidä jättää mitään tärkeätä, kuten lopullisia demovastauksia, koska sen sisältö suorastaan luvataan tuhota aika ajoin. Kurssin loppupuolella siellä toivon mukaan tehdään vapaaehtoista demoa, jonka suoranaisena tarkoituksena on saada palvelimen muisti täyteen ja toiminta muutenkin tukkoon. Tässä vaiheessa kurssia se tarjoaa turvallisen, maailmalta eristetyn, ympäristön shellin kokeiluun esimerkiksi tässä demossa.

Prosessinhallintaa: käynnissä olevien prosessien listaaminen

Luennoilla on tarkoitus aivan alkuvaiheesta asti käyttää komentoja, joilla käyttöjärjestelmän ja tietokoneen tilannetta voidaan tarkastella shellistä käsin. Tarkoitus tässä demossa on, että kokeilet näitä työkaluja aivan omin käsin, jotta mieleen jää yleiskuva siitä, millaisia työkaluja esimerkiksi on olemassa. Oman kokemuksen kautta ymmärrät paremmin myös, mistä luennolla milloinkin puhutaan.

Näytä oman shell-session prosessit:

ps

Tuloste näyttänee jotakuinkin seuraavalle:

[nieminen@itka203 ~]$ ps
  PID TTY          TIME CMD
26837 pts/0    00:00:00 bash
32559 pts/0    00:00:00 ps

Vasemmanpuoleinen sarake (PID) kertoo kunkin prosessin yksilöivän numeron; tästä lisää kurssin mittaan. Toinen sarake (TTY) kertoo sen terminaalin nimen, josta prosessia ohjataan ("tty" == TeleTYpewriter; varsin historiallinen nimike). Kolmas sarake (TIME) kertoo, kuinka paljon prosessi on käyttänyt suoritusaikaa yhteensä. Ylläolevassa tuloste-esimerkissä käyttäjä "nieminen" ei ole käyttänyt kovinkaan paljon yhteisiä resursseja. Tekstipohjaiset sovellukset käyttävät häviävän pieniä määriä aikaa, toisin kuin laskentaintensiiviset sovellukset; tästäkin paljon lisää kurssin mittaan. Viimeinen sarake (CMD) kertoo komennon, jolla kukin prosessi on käynnistetty.

Näytä kaikki tietyn käyttäjän prosessit (korvaa "nieminen" vaikka omalla tunnuksellasi tai millä vaan):

ps -u nieminen

Näytä kaikkien käyttäjien prosessit ("e" == every??):

ps -e

Näytä enemmän tietoja ("f"==full) yhden käyttäjän prosesseista:

ps -f -u nieminen

Tämä tuloste kertoo prosessin ID-tunnuksen ja komennon lisäksi myös muita tietoja. Saattaa näyttää vähän tältä:

UID        PID  PPID  C STIME TTY          TIME CMD
nieminen  1023 26837  0 20:12 pts/0    00:00:00 ps -f -u nieminen
nieminen 14995     1  0 Feb19 ?        00:00:00 SCREEN
nieminen 14996 14995  0 Feb19 pts/1    00:00:00 /bin/bash
nieminen 15010 14995  0 Feb19 pts/2    00:00:00 /bin/bash
nieminen 26836 26806  0 19:16 ?        00:00:00 sshd: nieminen@pts/0
nieminen 26837 26836  0 19:16 pts/0    00:00:00 -bash

Ensimmäinen sarake (UID) ilmoittaa nyt käyttäjän, jonka oikeuksin prosessia suoritetaan. Toinen sarake (PID) yksilöi prosessin. Kolmas sarake (PPID) ilmoittaa sen prosessin, joka on pyytänyt rivillä näytetyn prosessin käynnistymistä, tämän nimi on luontevasti vanhempiprosessi (ppid = "parent process id"). Neljäs sarake (C) kertoisi, kuinka paljon prosessoriaikaa kukin prosessi vie; tässä esimerkissä suoritusaika ei vaikuttaisi kovin relevantilta kysymykseltä. Viides sarake (STIME) kertoo, mihin aikaan prosessi on käynnistetty. Kuudes sarake (TTY) on jälleen terminaalin nimi. Seitsemäs (TIME) kertoo jälleen, paljonko prosessoriaikaa prosessi on vaatinut. Täydemmässä tulosteessa viimeinen sarake (CMD) on myös täydellisempi. Se kertoo pelkän komennon lisäksi myös argumentit, jotka komentorivillä on annettu.

Valitsimia voi yhdistellä. Esimerkiksi näytä enemmän tietoja kaikkien käyttäjien prosesseista:

ps -f -e

Tämän komennon tulosteessa osa riveistä on muiden normaalien käyttäjien prosesseja, mutta osa puolestaan on järjestelmän palveluiden prosesseja, jotka toimivat käyttäjäoikeuksin. Tällä tavoin voidaan rajata palveluiden oikeuksia samalla tavoin kuin normaalien käyttäjienkin. Kaikkien palveluiden ei missään nimessä tarvitse päästä käsiksi kaikkialle, koska ensinnäkin jokainen avoimeksi jätetty ovi on potentiaalinen tietoturva-aukko. Sen sijaan kukin palvelu kannattaa suunnitella käynnistettäväksi sellaisen käyttäjätunnuksen alle, jolla on minimaaliset oikeudet täsmälleen kyseisen palvelun toteuttamiseksi. Esimerkiksi WWW-palvelimella ei missään nimessä saisi olla kirjoitusoikeutta koko järjestelmään. Sen toiminta on syytä rajata esimerkiksi httpd -nimiselle käyttäjälle tai ryhmälle määrättyihin oikeuksiin.

Tuloste alkaa todennäköisesti seuraavalla rivillä:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jan28 ?        00:00:16 /sbin/init
root         2     0  0 Jan28 ?        00:00:01 [kthreadd]

Tuo käyttäjä root on kaikkivoipaisin käyttäjä, jonka oikeuksin voi tehdä järjestelmässä mitä vain. Prosessi, jonka id-numero on 1 ja komento /sbin/init on erikoisroolissa: käynnistyksen yhteydessä käyttöjärjestelmä käynnistää kyseisen init-prosessin, ja kaikki muut sittemmin käynnistetyt prosessit ovat sen lapsia. Myös prosessi 2, käyttöjärjestelmän säikeitä hallitseva palvelu, on erikoisroolissa (järjestelmä on käynnistänyt sen "ilman vanhempaa" eli ppid==0). Kaikki loput prosessit ovat jomman kumman prosessin (1 tai 2) jälkikasvua. Voinet verifioida tämän saamastasi tulosteesta.

Kokeile vielä seuraavaa epästandardia laajennosta, joka näyttää oikeanpuoleisessa sarakkeessa kauniina "ASCII-grafiikkana", mikä prosessi on minkäkin toisen prosessin lapsi tai vanhempi:

ps -e -f --forest

Prosessin 2 (kthreadd) lapsia ovat laitteistoa käsittelevät palvelut. Prosessin 1 lapsia ovat vähemmän laiteläheiset palvelut, mm. sshd -palvelu, joka odottaa salattuja pääteyhteyksiä, kuten se, jota tällä hetkellä käyttelet.

Vielä yksi tapa tutkia prosesseja... komenna:

top

Top näyttää reaaliaikaisen tilanteen prosesseista ja niiden aiheuttamasta resurssikuormasta. Topista pääsee pois näppäilemällä q.

Lisää tietoa ja kustomointimahdollisuuksia näkee tietenkin seuraavasti:

man ps
man top

Tiedostojen ja käyttöoikeuksien hallintaa

Unixmaisesta tiedostojärjestelmästä toteutuksineen puhutaan kurssilla myöhemmin lisää, mikäli ehditään. Katsotaan käyttäjän näkökulmaa tässä vaiheessa etäkoneen shellissä.

Komenna:

ls -l

Optiolla -l tiedostoja listaava ohjelma ls näyttää tiedostoista niiden nimen lisäksi lisätietoja, kuten käyttäjän ja käyttäjäryhmän, joille tiedosto kuuluu, sekä tiedoston käyttöoikeudet. Käyttöoikeudet näytetään vasemmalla puolella tulostetta, esimerkiksi seuraavasti:

-rwx--x--x. 1 nieminen nobody 9549  8.4. 13:54 a.out

Itse asiassa siitä näkyy tiedoston moodi muutenkin. Tulosteessa on 10 merkkiä, jotka ovat joko viiva - tai tietty kirjain. Viimeiset yhdeksän kertovat käyttöoikeuksista jakautuen kolmeen kolmimerkkiseen pätkään, joissa toistuvat järjestyksessä merkit r niinkuin 'read', w niinkuin 'write' ja x niinkuin 'execute'. Merkit vastaavat luku-, kirjoitus- ja suoritusoikeutta; jos merkin paikalla on viiva - niin kyseinen oikeus puuttuu. Kolmen merkin pätkät vastaavat käyttäjälle itselleen (esimerkissä käyttäjätunnus nieminen), ryhmälle (esimerkissä ryhmätunnus nobody) sekä aivan kaikille järjestelmän käyttäjille annettuja oikeuksia. Esimerkissä siis nieminen saa lukea, kirjoittaa ja suorittaa tiedostoa a.out; ryhmän nobody jäsenet saavat vain suorittaa; samoin muut kuin nieminen tai nobody -ryhmäläiset saavat suorittaa mutteivät muuta.

Oikeuksia voi muuttaa ohjelmalla chmod. Manuaali kertoo enemmän; tässä joitakin esimerkkejä:

chmod u+x TIEDOSTONIMI

Tiedoston omistajaksi merkitylle käyttäjälle (u niinkuin 'user') annetaan (+ niinkuin 'lisäys') oikeus suorittaa (x niinkuin 'execute') tiedosto, jonka nimi komennossa annetaan. Sen sijaan seuraava komento toimii päinvastoin:

chmod u-x TIEDOSTONIMI

Tässä jälkimmäisessä tiedoston omistajaksi merkityltä käyttäjältä (u niinkuin 'user') poistetaan (- niinkuin vähemmän) oikeus suorittaa (x niinkuin execute) tiedosto, jonka nimi komennossa annetaan.

Totuttele komentoon: kokeile tehdä vaikka joku humpuukitiedosto, anna ja poista sille oikeuksia ja katso kuinka ls -l -komennon tuloste muuttuu. Turvallisuuden vuoksi älä kajoa laajemmin tiedostojesi tai varsinkaan hakemistojesi käyttöoikeuksiin ennen kuin olet oppinut aiheen yksityiskohdat.

Tarkempia tietoja tiedostosta saa komennolla stat esimerkiksi seuraavasti:

stat hmm.txt

Tuloste on jotakin seuraavanlaista:

File: `hmm.txt'
Size: 4               Blocks: 8          IO Block: 4096   regular file
Device: fd09h/64777d  Inode: 786456      Links: 1
Access: (0644/-rw-r--r--)  Uid: (29067/nieminen)   Gid: (  100/   users)
Access: 2014-05-05 14:56:31.509949717 +0300
Modify: 2014-04-03 16:11:07.469291072 +0300
Change: 2014-04-03 16:11:07.469291072 +0300

Jätetään mielen päälle hautumaan, että tiedostoon liittyy oikeuksien (Access) ja oikeuksiin liittyvien omistajien (Uid, Gid) lisäksi mm. aikaleimoja viimeiseen käyttöhetkeen (Access), sisällön muutoshetkeen (Modify) ja metatietojen kuten käyttöoikeuksien muutokseen (Change). Tiedoston sijaintia laajemman struktuurin sisällä ilmoittaa yksilöllinen i-solmun numero (Inode). Joihinkin näistä tiedoista palataan kurssin tiedostojärjestelmiin liittyvässä osiossa, riippuen mihin tällä kurssikerralla ehditään.

Tiedostojen sisällön tutkimista

Mikä on tiedosto? Tähän mennessä varmaan ymmärretään, että se on jonkinlainen kokonaisuus, jolla on nimi, yksilöllinen osoite hakemistopuussa, omistaja, käyttöoikeuksia, pituus, aikaleimoja käyttö- ja muunteluajankohdista. Tiedosto voi sisältää esimerkiksi tekstin, kuvan, videopätkän tai suoritettavan ohjelman. Okei. Mutta miten esimerkiksi tekstitiedosto, kuvatiedosto ja suoritettava ohjelmatiedosto eroavat toisistaan?

Nyt katsotaan, miten pystyt selvittämään tasan tarkkaan, mitä tiedosto pitää sisällään. POSIX lupaa, että yhteensopivassa järjestelmässä toimii seuraava komento:

od tiedostonimi

Kokeile esimerkiksi:

od /bin/true

Tämä komento od eli "octal dump" tulosti nyt tiedoston /bin/true sisällön tasan tarkkaan siten, kuin se on, käyttäen oktaalinumeroita datan osoitteelle tiedoston alusta lukien (vasen sarake) sekä itse tiedolle (loput sarakkeet). Oktaalinumerot eivät välttämättä ole hauskin tapa katsoa tiedostoja, joten tällä kurssilla käytämme suosiolla epästandardia komentoa, joka suorakäyttökoneiltamme löytyy. Eli teemme POSIXista huolimatta seuraavaa:

hexdump -C /bin/true | less

(Muistat varmasti (?), että less näyttää putken vasemmalla puolella olevan komennon tulosteen vähän kerrassaan ja siten, että tulostetta voi selata edestakaisin.)

Tämä hexdump, kun sille antaa argumentin -C ja jonkin tiedoston osoitteen, niin se näyttää tiedoston sisällön kohtalaisen nätissä formaatissa, joka alkaapi tässä tapauksessa seuraavalla tavoin:

00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 3e 00 01 00 00 00  70 0f 40 00 00 00 00 00  |..>.....p.@.....|
00000020  40 00 00 00 00 00 00 00  20 5a 00 00 00 00 00 00  |@....... Z......|
00000030  00 00 00 00 40 00 38 00  08 00 40 00 20 00 1f 00  |....@.8...@. ...|
...

Vasemmalla on datan sijaintipaikka heksalukuna tiedoston alusta alkaen. Sitten on aina 16 kappaletta 8-bittisiä tavuja ja lopussa vielä sarake, jossa nämä 16 tavua on tulostettuna, mikäli ne sattuvat olemaan "selväkieliseen" ASCII-merkistön osuuteen kuuluvia eli "tulostettavia ('printable')" merkkikoodeja.

Tässä tapauksessa, kuten aika usein, tiedoston ensimmäisistä tavuista voi päätellä paljon siitä, mitä tiedosto pitää sisällään. Tässä tapauksessa ensimmäiset tavut ovat heksana 7f 45 4c 46, mihin sisältyvät numerokoodit 0x45, 0x4c ja 0x46 voidaan tulkita ASCII-merkistön mukaan merkkijonoksi ELF. Tiedosto ei todennäköisesti liity pitkäkorvaisiin haltioihin tai tonttuihin (engl. "elves", yksikkö "elf"), vaan mitä todennäköisimmin se sisältää ELF-muotoon tallennettua konekielistä ohjelmakoodia (ELF == "Executable and Linkable Format).

Voit selailla tiedostoa edestakaisin less-ohjelmassa nuolilla ja PageUp, PageDown -näppäimillä ja katsella, löytyykö sen sisältä mahdollisesti muitakin lukukelpoisia tekstejä. Olennaista on, että nyt tiedät, miten pystyt katsomaan tavu tavulta, bitti bitiltä, mitä mikäkin tiedostosi pitää sisällään. Voit huvikseen tutkia, miltä tietokoneen mielestä näyttävät esim. tekstitiedostot, kuvatiedostot, docx-dokumenttitiedostot, zip-paketit... (kahdessa viimeksimainitussa on jotakin yhteistä, muuten).

Työkaluohjelma file kokeilee heuristisesti, mikä tiedoston todennäköinen formaatti on:

file /bin/true

Kun on selvinnyt, että tämä /bin/true on ohjelmatiedosto, voidaan sen sisältöä tarkastella myös seuraavasti:

objdump -x /bin/true | less

Tulosteessa on kaikenlaisia toistaiseksi enemmän tai vähemmän mystisiä tekstejä ja heksanumeroita; jätetään toistaiseksi hautumaan.

(Reunahuomautuksena... tämä true -ohjelma on POSIX-standardin edellyttämä apuohjelma, joka manuaalin mukaan "ei tee mitään, onnistuneesti", tarkista vaikka komennolla man true... Se on siis vähän niinkuin jotkut meidän opiskelijat, mutta et Sinä, koska olet ilmeisesti tekemässä tätä demoa, mikä on enemmän kuin ei mitään...)

Osa 3: Tekstieditointia suoraan pääteyhteydellä

"Emacs tai Vim - muuten ei ole nörtti"

(lentävä lause henkilökunnan kahvihuoneessa; alkuperä tuntematon)

Normaaliolosuhteissa käytämme ohjelmakoodin ja järjestelmäylläpidon tehtäviin työpaikan tarjoamia tai itse hankittuja graafisia työkaluja, joihin mm. IDEt ja tekstieditorit lukeutuvat. Materiaalit kehitetään ja testataan lokaalisti, ylläpidetään jaetussa versionhallinnassa ja testatut tuotantoversiot jaellaan aikataulun mukaisesti asiakkaille. Monien nykyisten tuotteiden tapauksessa tämä tarkoittaa asiakkaan tuotantopalvelimessa toimivan palvelinohjelmiston päivittämistä.

Joskus tarvitsee hätätilanteessa (tai siksi että se on vaan nopeampaa kuin kopioida tiedostoja edestakaisin) tehdä jotakin ylläpitotoimenpiteitä suoraan pääteyhteydellä tekstieditorilla, jossa ei ole graafista käyttöliittymää. Mm. näitä tilanteita varten tällä kurssilla totutellaan tekstieditointiin päätteellä. Kehittyneempien tekstieditorien käyttöliittymät on myös kehitetty lähtökohtaisesti erinomaisen tehokkaiksi. Modernimmissa IDEissäkin on usein mahdollista säätää asetuksista näppäinkomennot vastaamaan "vanhojen kunnon" tekstieditorien tyyliä, jolloin mm. ei tarvitse juurikaan siirtää käsiä näppäinten keskeltä hiirelle, eikä edes nuolinäppäimillekään asti! Tekstin tuottaminen ja siirtely paikasta toiseen voi tällöin tulla huomattavan paljon nopeammaksi toimenpiteeksi kuin ajattelu, jota ohjelmien luominen tietysti ensisijaisesti vaatii. Mikäli käytät enemmän aikaa koodin tekniseen kirjoittamiseen kuin ratkaisun keksimiseen, käytät melko varmasti vääriä työkaluja tai et osaa vielä hyödyntää kalustoa riittävän tehokkaasti!

Alkupuolella tätä demoa nähtiin nano, joka on helppokäyttöinen, mutta jossa ei oikeastaan paljon muita ominaisuuksia ole. Oikeasti tekstin editointi vaatii järeämpää kalustoa.

POSIX-standardi määrää, että yhteensopivasta järjestelmästä löytyy vähintään yksi "visuaalisesti orientoitunut" tekstieditori, joka käynnistyy komennolla vi ja toimii aina vähintään juuri tietyllä tapaa. Käytännössä nykyään esim. meidän suorakäyttökoneillamme tuo komento käynnistää laajennetun editorin nimeltä vim eli "Vi IMproved". Vim on hyvin käyttökelpoinen ja tehokas tekstieditori, mutta sen käyttöönotossa on jonkin verran jyrkempi oppimiskäyrä kuin nano:ssa.

Toinen hyvin kehittynyt ja tehokas tekstieditori on emacs, jonka saa helposti asennettua moniin unixmaisiin käyttöjärjestelmiin - esimerkiksi meidän suorakäyttökoneillamme se löytyy valmiiksi asennettuna.

Jos aikasi on todella rajallinen, riittää hätätilanteessa käyttää nanoa, jolla pystyy tekemään tämän sekä myöhemmät tämän kurssin demot, vaikkakaan ei kovin tehokkaasti.

Pidemmän päälle suositeltavaa (ehkä jopa ajankäytön suhteen) on valita joko vim tai emacs ja perehtyä sen ominaisuuksiin yksi kerrallaan. Tämän demon kirjoittajan oma suosikki on ilman muuta emacs, mutta sotien välttämiseksi tuli nyt tälläkin kertaa mainittua vim ensiksi.

Keväällä 2016 näitä demoja oli tekemässä myös syventävän kurssin "Linux-palvelimen ylläpito" opiskelijoita. Heille suosittelen vimiä, koska se löytyy emacsia useammin palvelimilta. Kyseinen porukka myös unohtakoon sen nanon ihan suosiolla!

Lopuksi mainittakoon automaattinen tekstieditointi, joka voi joskus tarjota nopeimman ja helpoimman keinon etsi- ja korvaa -tyylisiin tai muihin mekaanisiin tekstinkäsittelytehtäviin. Tyypillisiä työkaluja ovat ainakin POSIX-standardin vaatimat sed ja awk. Näihin tuskin ehditään perehtyä tällä kurssilla ainakaan muutamaa esimerkkiä pidemmälle. Idea on, että näillä työkaluilla voi etsiä ja korvata merkkijonon kerralla vaikka 10000 tekstitiedostosta, joissa on yhteensä teratavu materiaalia. Käsipelillä menisi ikuisuus ja esim. usean gigatavun kokoista tekstitiedostoa tuskin pystyisi edes avaamaan tekstieditorissa.

"Entry level": nano

Nanon käynnistäminen käytiin läpi tämän demon alussa. Melkein kaikki toiminnot näkyvät ruudun alalaidassa. Control-näppäimen painaminen kirjoitetaan lyhyesti väkäsellä eli sirkumfleksilla, esim. ^G tarkoittaa samaa kuin näppäily Ctrl-g. Kyseinen näppäilyhän antaa tarkemman ohjesivun, jonka perusteella varmaan pärjäät tarvittaessa.

Huomionarvoinen lisätarkennus liittyy useamman peräkkäisen rivin kopiointiin: Mene riville, josta alkaa haluamasi kopioitava pätkä. Sitten tuhoa ("kill") Ctrl-k:ta painamalla peräkkäisiä rivejä niin paljon kuin haluat lopulta kopioida. Peräkkäin tuhotut rivit tallentuvat itse asiassa tuhoamispuskuriin ("kill buffer"), jonka saat takaisin näppäilemällä Ctrl-u ("un-kill"(?)). Mene kohtaan, johon haluat laittaa kopion ja näppäile toisen kerran Ctrl-u. Kopio on valmis ja voit editoida sitä eteenpäin.

Ohjelmakoodia on paljon helpompi editoida editorilla, joka tukee syntaksin mukaista värikoodausta. Jopa nanossa jonkinlainen köpsähtävä perustuki onneksi löytyy. Ohjeet värityksen käyttöön nanossa annetaan C-kielen editointia edellyttävän demon yhteydessä.

Toivottavasti uskaltaudut kuitenkin edes hiukan kokeilemaan jompaa kumpaa tehokkaammista editoreista, vaikka niiden oppimiskäyrä on aluksi jyrkempi.

"Advanced level": emacs

Emacs -tekstieditorin ensimmäinen versio on peräisin vuodelta 1976. Kuinka hyväksi spesifiin tarkoitukseen tehty ohjelmisto voi kehittyä 41 vuodessa, kuten emacs vuoteen 2017 mennessä? Vinkki: aika hyväksi. Vuonna 2017 meidän suorakäyttökoneellemme on asennettu versio "GNU Emacs 23.1.1". Lisätietoa emacsista esim. wikipedia http://en.wikipedia.org/wiki/Emacs ja virallinen sivu https://www.gnu.org/software/emacs/

Tämä editori käynnistyypi komennolla:

emacs

Ensimmäisellä käynnistyskerralla emacs havaitsee, ettet ole aiemmin käynnistänyt sitä, ja tarjoilee ohjeita. Ota vastaan, jos siltä tuntuu. Tässä demolapussa pystytään antamaan vain kriittisimmät selviytymisohjeet. Oletusasennuksessa emacs tunnistaa 2000 erilaista komentoa, ja siihen voi ohjelmoida lisää ominaisuuksia miten tahtoo... valmiita lisälaajennuksia on netti pullollaan.

Selviytyminen, osa 1: Emacsin saa suljettua näppäilemällä Ctrl-x Ctrl-c eli ensin Control ja x-näppäin ja sen perään Control ja c. Muistaakseni on ihan kiva tietää, miten ohjelman saa suljettua.

Selviytyminen, osat 2 jne: Emacsissa voi olla auki monta tiedostoa yhtä aikaa niin sanotuissa "puskureissa". Paljolti perustoiminnot perustuvat yhden tai parin näppäimen näppäinyhdistelmiin, jotka laukaisevat toimenpiteitä. Melkein jokainen näppäimen painallus laukaisee erikseen ohjelmoitavissa olevan toiminnon, yksinkertaisimmillaan vastaavan merkin lisäämisen näkyvissä olevaan puskuriin osoittimen kohdalle.

Emacsissa on oma tutoriaali, jonka saa päälle näppäilemällä Ctrl-h t. Ohje koostuu tekstitiedostosta, joka avautuu suoraan editoriin itseensä ja käytännön tekemisen kautta opastaa alkuun.

Esimerkkinä joitakin aivan yksinkertaisimpia komentoja suomeksi kuvattuna tässä:

  • Uuden tiedoston voi ladata uuteen editointipuskuriin eli "ikkunaan" komennolla Ctrl-x Ctrl-f ("f" == find file) ja kirjoittamalla dialogiriville tiedoston nimen. Normaali tabulaattori-apu toimii tässäkin täydentämään tiedostojen nimiä. Tiedoston ei tarvitse olla aikaisemmin olemassa, vaan voi "etsiä" tiedoston, jonka haluaa kirjoittaa alusta lähtien uudelleen.
  • Nykyisessä puskurissa tehdyt muutokset tallennetaan alkuperäiselle nimelle näppäilemällä Ctrl-x Ctrl-s ("s" == save) tai uudelle eri nimelle näppäilemällä Ctrl-x Ctrl-w ("w" == write), jolloin emacs kysyy tallennettavan tiedoston nimeä. Ruudun alalaidassa näkyy merkit ** silloin, kun nykyisessä puskurissa on tallentamattomia muutoksia.
  • Avoinna olevien puskurien välillä vaihdetaan näppäilemällä Ctrl-x b eli Control ja x ja sen jälkeen ilman controlia pelkkä b-kirjain ("b" == buffer). Sitten vielä kirjoitetaan sen puskurin nimi, johon halutaan vaihtaa; tabulaattoritäydennys auttaa, niin ei tarvitse muistaa. Muistaminen on vaikeata, joten onneksi se on useimmiten tehty tarpeettomaksi.
  • Emacsissa toimii melkein samat näppäinkomennot, joiden aiemmin kerrottiin toimivan bashin komentorivillä, mm. rivillä siirrytään samalla tavoin eteenpäin ja taaksepäin, ylös ja alas. Ctrl-k leikkaa rivin lopun ja Ctrl-y tuo tuhotun asian takaisin jne.
  • Pätkien leikkaus ja kopiointi hoituu "merkin" avulla: Ctrl-Space jättää nykyiseen paikkaan merkin, jolloin alarivi ilmoittaa "Mark set". Kohdistinta voi sitten siirtää ja kaikki äsken laitetun merkin ja nykyisen sijainnin välillä kuuluu alueeseen (region), jonka voi esimerkiksi kopioida Alt-w tai leikata Ctrl-w. Leikatun/kopioidun tekstin voi palauttaa mihin tahansa kohtaan näppäilyllä Ctrl-y. Välittömästi tämän jälkeen on mahdollista näppäillä Alt-y, mikä tuo historiasta aikaisemmin leikattuja/kopioituja pätkiä.
  • Jos merkkaus lähtee päälle vahingossa, merkkauksen voi lopettaa näppäilemällä tuplat eli Ctrl-Space Ctrl-Space; alarivi ilmoittaa "Mark deactivated"
  • Itselle vieraita toimintoja saattaa välillä lähteä vahinkonäppäilyjen kautta päälle. Niistä pääsee yleensä pois näppäilemällä peruutuspyynnön Ctrl-g, ja jos editoitava teksti muuttui vahingossa väärin, niin peruutustoiminto eli Undo toimii aina näppäilyllä Ctrl-x u ("u" == undo). Peruutus on monitasoinen, kuten olettaa sopii.

Loput 2000+ komentoa eivät mahdu tähän ohjeeseen; lisää manuaalissa https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html ja lukuisissa tutoriaaleissa, joita voi etsiä Internetistä vaikkapa hakusanalla "emacs tutorial".

"Advanced level": vim

Myös vi -editorin ensimmäinen versio on julkaistu vuonna 1976. Toistetaan siis kysymys, että kuinka hyväksi spesifiin tarkoitukseen tehty ohjelmisto voi kehittyä 41 vuodessa, kuten vi vuoteen 2017 mennessä? Tähän vastaus on sama kuin emacsin suhteen. Vinkki: aika hyväksi. Alkuperäinen vi on myös standardoitu POSIXissa. Matkan varrella, vuosina 1987-1993, syntyi nykyisin suosittu laajennettu, eikä täysin standardin mukainen "Vi IMproved", joka esimerkiksi meidän suorakäyttökoneiltamme löytyy. Lisätietoa esim. wikipediasta http://en.wikipedia.org/wiki/Vim_%28text_editor%29 ja Vimin omilta sivuilta http://vim.sourceforge.net/ .

Selviytyminen, osa 1: Vimin saa suljettua suljettua näppäilemällä ESC : q !  Enter. ESC siirtää vimin tilaan, joka odottaa komentoja, jos se oli vahingossa jossain muussa tilassa. Sitten annetaan komento :q ("q"==quit) ja kirjoitettu komento kuitataan enterillä. Jos on tallentamattomia muutoksia joita ei haluta säilyttää, niin loppuun pitää laittaa vielä huutomerkki ! ("!"=="tosissaankin").

Selviytyminen, osat 2 jne: Vimissä on erikseen komentotila (normaalitila) ja kirjoitustila, ja lisäksi on muita tiloja erityistarpeeseen, kuten "visuaalinen tila" tekstin maalaamiseen ja leikkaamiseen leikepöydälle. Idea on tehdä tekstin poistot, leikkaamiset, liimaamiset ynnä muut muutokset komentotilan kautta, ja kirjoittaa uutta tekstiä tarvittaessa kirjoitustilassa. Kirjoitustila menee päälle esim. näppäilyllä i ("i"==insert). Kirjoitustilasta pääsee takaisin komentotilaan näppäilemällä ESC.

Varoitus: Kun mahdollisesti leikkaat jostain tekstiä ja liimaat sen pääteyhteydessä, niin ole varovainen (myös) Vimin kanssa. Jos vim on komentotilassa, niin pääteikkunaan copy-pastettua tekstiä käsitellään tietysti merkki kerrallaan kuin komentoja, mikä saattaa aiheuttaa virheiden ilmaantumista, pahimmillaan editoitavan tekstin muuttumista, häviämistä ja Vimin asetusten muuttumista!

Vimillekin löytyy sen oma pika-tutor, jonka saa suorakäyttökoneella käyntiin komennolla:

vimtutor

Ohje koostuu tekstitiedostosta, joka avautuu vim -editoriin. Kyseinen ohje lupaa opettaa Vimin peruskäytön puolessa tunnissa. Kokeilin itse, ja näin siinä voi käydä. Eli ajankäytön suhteen kumminkin aika minimaalista suhteessa loppuelämäksi saatavaan hyötyyn.

Vim jakaantuu erilaisiin tiloihin, jolloin tälläiseen ajattelutapaan tottumaton käyttäjä hämmentyy aluksi, koska aiemmin tutuissa graafisissa editoreissa tällaista toimintamallia ei ole. Esimerkiksi komentotilassa näppäily x hävittää osoittimen alla olevan merkin. Toki sen saa takaisin näppäilemällä u niinkuin "undo". Vim (kuten emacskin) on suunniteltu nopeaksi editoriksi. Oikein käytettynä tekstin muokkaaminen on todella tehokasta, mutta aluksi sen opettelu mahdollisesti vaatii graafisia kollegoitaan enemmän aikaa ja vaivaa.

Tarkkaile ettei Caps-Lock ole vahingossa jäänyt päälle kun käytät normaalitilaa. Isoilla kirjaimilla on tässä väliä. Tiettyjä aloittajalle riittäviä komentoja:

a   siirtyy lisäystilaan kursorin oikealle puolelle.
A   siirtyy lisäystilaan nykyisen rivin loppuun.
i   siirtyy lisäystilaan kursorin kohdalle.
I   siirtyy lisäystilaan rivin nykyisen alkuun.
h,l liikkuu vasemmalle, oikealle. Rivin alussa/lopussa ei siirrytä
    automaattisesti toiselle riville!
j,k siirtyy seuraavalle, edelliselle riville.
u   palauttaa muutoksista, "undo"
x   poistaa kursorin kohdalla olevan merkin.
0   (numero nolla) siirtää kursorin rivin alkuun.
$   (dollarimerkki) siirtää kursorin rivin loppuun.
o,O Luo uuden rivin nykyisen rivin alapuolelle, yläpuolelle.
    Siirtää kursorin sinne lisäystilassa.
w,e siirtää kursorin seuraavan sanan alkuun, loppuun.
:   siirtyy Vimin komentoriville. Pois pääsee painamalla askelpalautinta
    tai ESC näppäintä.
v   siirtyy visuaaliseen-/valintatilaan.

Osaan edellisistä komennoista saa lisämausteita kirjoittamalla numeroita ennen komentoa, esim. 3j siirtyy kolme riviä alemmaksi.

Valintatilassa editori näyttää kursorin ja sen paikan välisen alueen korostettuna, jossa kursori oli valintatilaan siirryttäessä, jolloin tämän korostetun alueen voi vaikka kopioida tai poistaa. Valintatilassa painamalla y editori kopioi korostetun alueen, painamalla d leikkaa sen (poistaa samalla kun kopioi). Täten leikepöydälle kopioidun alueen voi liimata uuteen paikkaan näppäilyllä p.

Vim on monipuolinen editori, josta löytyy kasa muitakin tiloja sekä komentoja, oma skriptikieli sekä monia muita herkkuja.

Mikä editori on paras?

Joidenkin mielestä emacs on paras, joidenkin mielestä vim. Molemmat on tekstin editointiin riittäviä, mutta jompikumpi on osattava, että voi osallistua keskusteluun :).

Molemmat editorit ovat kokeneen käyttäjän käsissä luultavasti tehokkain toistaiseksi keksitty tapa siirtää tekstiä henkilön pään sisältä tietokoneelle.

Molempien ero esim. nano -editoriin tai Windowsin notepad -editoriin on suurin piirtein sama kuin Boeing 777:n ero paperilennokkiin.

"Automated level": sed, awk

TODO (ei vielä 2015 eikä 2016 eikä 2017): Ihan muutama esimerkki siitä, miten search&replace ym. hoituu automaattisesti esimerkiksi POSIXin määräämiä apuohjelmia sed ja awk käyttäen.

Osa 4: Skripti

Varioidaan ensimmäisessä demossa tehtyä palautustehtävää. Tällä kertaa automatisoidaan toimenpide, eli tehdään tekstieditorilla noin seitsemän riviä pitkä shell-skripti, joka tuottaa halutunlaisen tulosteen.

Palautettavan tiedoston muoto

Tiedoston muodon tulee olla seuraavanlainen (huomaa pienet erot demossa 1 tehtyyn):

  1. Tiedoston nimi on kj17_demo2_tuloste.txt. Ensimmäisen rivin sisältönä on jälleen whoami -ohjelman tuloste.
  2. Seuraavalle riville tulee komennon pwd tuloste. Oletetaan että olet toisen demon vastauksille tekemässäsi hakemistossa, ja kyseisen hakemiston nimihän tuosta pitäisi täten tulostua, siis esimerkiksi jotakin tyyliin /nashome2/nieminen/kj17/demo2.
  3. Seuraavalle riville tulee komennon uname -a tuloste. Tästä tarkastaja näkee, että olet yliopiston suorakäyttökoneella, kuten harjoitteeseen kuuluu.
  4. Seuraavalle riville tulee komennon date tuloste. Tästä näkee, milloin demo on tehty.
  5. Seuraavalle riville tulee komennon ls -l tuloste. Tulosteesta näkyy mm. tässä tehtävässä luotavan skriptitiedoston nimi ja käyttöoikeudet.
  6. Seuraaville riveille tulee komennon ps -u `whoami` -f tuloste. Tulosteesta tarkastaja näkee mm. että käynnissä on screen-ohjelma, jota tässä demossa jumpataan (lisäksi näkyy toki irssi, mutt, nano ym. ohjelmat, joita mahdollisesti käytät samaan aikaan; emacsista saa respectiä välittömästi, samoin vimistä... nanosta vähemmän, mutta jokin editori on oltava käynnissä screenissä). Erityisesti näkyy myös että käynnissä on shellistä ajettu omatekemä skripti.
  7. Loppuun tulee vielä listaus itse siitä skriptitiedostosta, jolla edellisetkin rivit tuotettiin. Tähän annetaan valmis ohje alempana.

Shell-skripti, joka tuottaa palautustiedoston

Mikä ja miksi on skripti? Skripti (engl. script) eli "komentojono" tai "komentoriviohjelma" on shellin, esimerkiksi bashin, ymmärtämän syntaksin mukainen ohjelma, jonka shell lukee, tulkkaa ja suorittaa rivi riviltä. Laajemmin ajateltuna skriptiksi voitaisiin sanoa millä tahansa tulkattavalla kielellä (esim. python, perl, lua, php, matlab, ...) tehtyä ohjelmaa, mutta käyttöjärjestelmien mielessä kiinnostavaa on tietysti juuri käyttöjärjestelmäkuorella eli shellillä ajettavat skriptit esimerkiksi käyttöjärjestelmän ylläpitotehtävien (käynnistys ja alasajo, logit, päivitykset, varmuuskopioinnit, ...) hoitamiseen.

Yksinkertaisimmillaan skripti koostuu peräkkäisistä komennoista, joita voisi yhtä hyvin kirjoittaa ja suorituttaa interaktiivisesti peräkkäin. Skriptiin kirjoitettuna ne jäävät kuitenkin talteen mahdollista myöhempää uudelleenkäyttöä varten. Useamman suoritettavan komentorivin kirjoittaminen on joka tapauksessa helpompaa ja vähemmän virhealtista tekstieditorilla kuin suoraan interaktiivisesti. Shell-skriptit voivat myös ottaa normaalien ohjelmien tapaan argumentteja, ja niihin voidaan kirjoittaa normaaleja ohjelmointirakenteita kuten muuttujia, aliohjelmia, silmukoita ja ehtoja. Shell-skriptit ovat todellinen järjestelmäylläpitäjän tehotyökalu.

Aloitetaan harjoitteet yksinkertaisesta päästä: Käytä valitsemaasi tekstieditoria yhdessä screen -ohjelman tarjoamassa ikkunassa ja kirjoita peräkkäisille riveille ylläolevassa tehtäväkuvauksessa tarvittavat komennot. Käytä toista screen -ohjelman tarjoamaa ikkunaa skriptin kokeilemiseen ja tulosteen oikeellisuuden tarkastamiseen.

Ensimmäisellä rivillä skriptissä tulee ilmoittaa risuaidan ja huutomerkin jälkeen shell-ohjelman eli meidän esimerkeissämme bashin sijainti tiedostojärjestelmässä. Skriptisi tulee siis alkamaan jotakuinkin näin:

#!/bin/bash
whoami > kj17_demo2_tuloste.txt
...

Huomaa, että tiedoston kj17_demo2_tuloste.txt aiempi sisältö häviää, kun ohjataan tuloste väkäsellä. Jatkaminen edellisen sisällön perään edellyttää kahden väkäsen käyttöä. Välilyönnit tulkitaan erotinmerkeiksi jne., joten ole edelleen perusvarovainen ja koeta etukäteen hahmottaa mitä suorituksissa tapahtuu.

Tulevassa (mahdollisesti vapaaehtoisessa) demossa opetellaan tekemään toimintavarmempia ja turvallisempia skriptejä, joille voi antaa kohdetiedoston nimen argumenttina ja jotka kieltäytyvät tekemästä tuhoisaa toimenpidettä, jos kohdetiedosto on jo olemassa. Mutta ei sekoiteta päätä vielä sillä, vaan kovakoodataan tuo tulostetiedoston nimi vaikkapa juuri kj17_demo2_tuloste.txt.

Skripti pitää ajaa oleskeluhakemistosta, eli komentamalla:

./demo2_skripti.sh

Tätä varten tiedoston käyttöoikeuksiin pitää lisätä suoritusoikeus käyttäjälle itselleen. Käytä siis komentoa chmod sopivasti. Älä lisää muita kuin välttämättömät oikeudet! Tässä vaiheessa tarvitset vain suoritusoikeuden käyttäjälle.

Kokeile skriptiä yhdessä screen-ikkunassa ja katso, että tuloste vastaa speksiä, esim:

cat kj17_demo2_tuloste.txt

Editoi tarpeen mukaan skriptiäsi siinä screen-ikkunassa, jossa editori on auki. Keskustele tarvittaessa ircissä kolmannessa screen-ikkunassa...

Tulostetiedoston lopussa halutaan vielä tehtävän tarkastamisen yhteydessä nähdä itse skriptin sisältö. Tämä hoituu sillä, että skriptisi viimeinen rivi on TÄSMÄLLEEN seuraava:

cat $0 >> kj17_demo2_tuloste.txt

Tätä älä toistaiseksi modaa mitenkään. Myöhemmin kurssilla selviää, millaisia potentiaalisia ongelmia tällä voisi vahingossa saada aikaan. Tämä valmiiksi annettu viimeinen rivi ohjaa kohdetiedoston perään cat -ohjelman tulosteen. Catille on annettu argumentiksi $0, joka skriptiä ajettaessa korvautuu komennolla, jolla skripti itse on suoritettu eli komennoksi muodostuu tässä oikeastaan automaattisesti cat ./demo2_skripti.sh >> kj17_demo2_tuloste.txt. Lopputulemana kirjoittamasi skriptin sisältö siis tulostuu tulostiedoston perään. Dollarimerkillä alkavista jutuista puhutaan myöhemmin lisää. (En tiedä, onko $0:n käyttö tässä standardin mukaista, mutta meidän yhteisessä toimintaympäristössä saadaan nyt tällä tavoin yhteen tarkastettavaan tiedostoon kaikki tarvittava eli tulosteet, joista nähdään, että screen-ohjelmaa ja tekstieditoria on oltu käyttämässä yhtäaikaa sekä myöskin itse tekemäsi skripti, jolla tuloste on luotu; irssin näkymisestä prosessilistauksessa respectiä, vaikka sitä ei tämän demon puitteissa vaaditakaan).

Osa 5: Pakollinen palautustehtävä

HUOM: Keväällä 2017 kurssin demot ja niiden palautus hoidetaan mahdollisimman pian ilmoitettavalla tavalla. Aiemmin käytetyn järjestelmän ylläpito on haastavaa juuri tällä hetkellä. Korvaavan (oletettavasti vain tänä vuonna väliaikaisesti käytettävän) tavan sommittelu on kesken.

HUOM 2: Tehtävän voi aivan hyvin tehdä jo ja tarkistaa, että palautettava tiedosto on oikean muotoinen. Palautat sen vaan sitten, kun palauttaminen saadaan mahdolliseksi!