Sisend, väljund, torud ja suunamine
Loogika
Kõige tähtsam mõte:
- käsk võib kirjutada tavalist väljundit
- käsk võib anda ka eraldi veateateid
- tavalise väljundi võib suunata faili
- tavalise väljundi võib anda teisele käsule
- käske saab ka lihtsalt järjest või tingimusega käivitada
Need ei ole sama asi. Faili suunamine, toru ja tingimuslik käsujada lahendavad eri probleeme.
Kiirülevaade
Eesmärk on panna käsud koostööd tegema: salvesta väljund, ühenda käsud või käivita järgmine samm tingimusega.
| Märk või käsk | Milleks | Mida tavaliselt näed |
|---|---|---|
> | kirjuta stdout faili üle | ekraanil vähem, failis uus sisu |
>> | lisa stdout faili lõppu | fail kasvab, vana sisu jääb alles |
| | anna stdout järgmise käsu sisendiks | näed tavaliselt viimase käsu tulemust |
; | käivita käsud järjest | järgmine käsk jookseb igal juhul |
&& | jätka ainult edu korral | järgmine käsk jookseb ainult 0 koodi järel |
|| | käivita varuplaan vea korral | järgmine käsk jookseb vea järel |
2> | suuna veateated faili | stderr läheb eraldi faili |
tee | näita ja salvesta korraga | väljund on ekraanil ja failis |
Lõpetuskood ei paista otse välja; vajadusel küsi seda käsuga echo $?.
Tüüpilised algaja vead
- aetakse segi
;ja| - kirjutatakse fail kogemata
>abil üle, kuigi taheti lisada>> - eeldatakse, et
sudo echo ... > failannab suunamisele samuti root-õiguse - imestatakse, miks edukas käsk vaikis, kuigi väljund läks tegelikult faili või torusse
1. Tavaline väljund, veaväljund ja lõpetuskood
Käsureal on hea eristada kolme mõistet:
stdout: tavaline väljund, mida käsk kirjutabstderr: eraldi veaväljund vigade ja hoiatuste jaoks- lõpetuskood ehk
exit code: märge selle kohta, kas käsk lõppes edukalt
Praktiline rusikareegel on:
0tähendab tavaliselt edu- mõni muu arv tähendab tavaliselt, et midagi läks valesti
Kui tahad näha viimase käsu lõpetuskoodi, saad kasutada:
ls sonad.txt
echo $?
ls puuduv_fail
echo $?
See mõte muutub oluliseks hiljem siis, kui jõuame märkideni && ja ||.
2. > kirjutab faili
Kui tahad käsu väljundi faili panna, kasuta märki >.
echo tere > sonad.txt
cat sonad.txt
Siin:
echo teretoodab teksti>suunab selle failicat sonad.txtnäitab tulemust
Oluline reegel: > kirjutab vana sisu üle.
3. >> lisab faili lõppu
Kui tahad olemasolevale failile juurde lisada, kasuta märki >>.
echo esimene > read.txt
echo teine >> read.txt
cat read.txt
Tulemus on:
esimene
teine
Peamine vahe on lihtne: > kirjutab üle, >> lisab lõppu.
4. Toru |
Toru ei kirjuta väljundit faili. Ta saadab ühe käsu väljundi järgmise käsu sisendiks.
Näide:
printf 'üks\nkaks\nkolm\n' | wc -l
Siin:
printftoodab kolm rida- toru
|saadab need edasi wc -lloeb kokku, mitu rida tuli
See on teistsugune loogika kui > abil faili kirjutamine.
5. Järjestikused käsud: ;
Märk ; tähendab lihtsalt: käivita järgmine käsk pärast eelmist.
pwd ; ls ; date
Siin käivitatakse kolm käsku järjest. ; ei anna andmeid ühest käsust teise edasi. Vahe on lihtne: ; käivitab käsud järjest, | ühendab käsud voona.
6. && ja ||
Need kaks märki lisavad käsujadale tingimuse. Nad ei vaata faili sisu ega toru kaudu tulevaid ridu, vaid eelmise käsu lõpetuskoodi.
&&
mkdir proov && cd proov
See tähendab: tee teine käsk ainult siis, kui esimene õnnestus.
||
grep 'midagi' puuduv.txt || echo 'otsing ebaõnnestus'
See tähendab: tee teine käsk siis, kui esimene ebaõnnestus.
Võrdlus
false ; echo 'see käivitus ikkagi'
false && echo 'seda ei näe'
false || echo 'varukäsk läks tööle'
Siin juhtub:
;järel läheb järgmine käsk alati käima&&järel järgmine käsk ei käivitu, sest esimene ebaõnnestus||järel järgmine käsk käivitub just sellepärast, et esimene ebaõnnestus
7. Vead ja 2>
Tavaline väljund ja veateated ei ole käsureal päris sama asi.
- tavaline väljund läheb tavaliselt
stdoutkaudu - vead lähevad tavaliselt
stderrkaudu
Kui tahad vead eraldi faili panna, kasuta:
ls puuduv_fail 2> vead.txt
cat vead.txt
Siin:
2>tähendab veaväljundi suunamist- tavaline väljund läheks endiselt ekraanile
Kui tahad veateate lihtsalt ära peita, siis võid kirjutada:
ls puuduv_fail 2> /dev/null
/dev/null on erifail, kuhu saadetud väljund kaob ära. Seda võib mõelda kui musta auku väljundile. Aprillinaljana öeldakse vahel, et /dev/null sai täis, aga päriselt tähendab see lihtsalt kohta, kuhu saab midagi teadlikult “mitte kuhugi” saata.
8. tee
tee on kasulik siis, kui tahad väljundit korraga ekraanil näha ja faili salvestada.
Näide:
printf 'Tallinn\nTartu\nNarva\n' | tee linnad.txt
cat linnad.txt
Kui tahad faili lõppu lisada, kasuta:
printf 'Pärnu\n' | tee -a linnad.txt
9. 2>&1 ja muud keerulisemad kujud
Kui tahad ühendada veaväljundi tavalise väljundiga, kohtad kuju:
find . -name '*.md' > tulemused.txt 2>&1
See tähendab, et nii tavaline väljund kui ka vead lähevad samasse faili.
See ei ole esimene kuju, mida pähe õppida, aga hea on teada, et selline võimalus on olemas.
10. Miks sudo echo ... > fail ei tööta nii, nagu algaja ootab
Paljud proovivad kuju:
sudo echo 'naide=1' > /etc/naide.conf
Aga siin teeb ümbersuunamise > sinu praegune shell, mitte sudo.
Sellepärast kasutatakse sageli hoopis sellist kuju:
echo 'naide=1' | sudo tee /etc/naide.conf
Peamine loogika on:
sudo echo ... > failei anna root-õigust shelli suunamiselesudo tee failavab faili protsessis, millel on vajalikud õigused
11. Kui väljund ei ilmu kohe
Mõni programm ei kirjuta iga rida kohe ekraanile või torusse edasi, vaid kogub väljundi vahepeal puhvrisse.
See tähendab:
- terminalis töötav programm võib näidata ridu kohe
- sama programm toru või faili kaudu võib väljundi edasi anda hiljem
Pythoni puhul kohtab seda sageli. Selleks on olemas näiteks:
python3 -u programm.pyprint(..., flush=True)
See on juba natuke järgmise taseme teema, aga hea on teada, miks mõni toru “vaikib” kauem kui ootasid.
Minitest
- Loo fail käsuga
echo tere > fail.txt. - Lisa teine rida käsuga
echo maailm >> fail.txt. - Näita faili sisu käsuga
cat. - Ühenda kaks käsku toruga, näiteks
printf ... | wc -l. - Võrdle käske
pwd ; lsjapwd | ls. - Proovi, kuidas
false && echo okerineb käsustfalse || echo ok.
Peatüki täisspikker
Algaja
Eesmärk
Ühenda käske nii, et ühe väljund saab järgmise sisendiks, või saada väljund faili; vea- ja tavaväljundit tasub mõelda eraldi.
Põhikäsud
echoprindi tekstprintfvorminda tekstcatnäita failiteeekraan ja failwcloe kokku
Olulisemad lipud, märgid ja kiirnupud
>stdout faili>>lisa stdout faili lõppu juurde|anna edasi järgmisele;käivita lihtsalt järjest&&tee edasi edu korral||tee edasi vea korral2>stderr eraldi faili2>&1stderr samasse kohta/dev/nullmust auk väljundile
Tüüpilised kujud
käsk > valjund.txtstdout failikäsk >> logi.txtlisa stdout faili lõppu juurdekäsk 2> vead.txtstderr eraldikäsk > valjund.txt 2> vead.txteralda mõlemadkäsk 2> /dev/nullpeida veateatedcat fail.txt | wc -ltoru loendussekäsk ; järgminejärgmine alatikäsk && järgminejärgmine ainult edulkäsk || varuplaanvaruplaan vea korralkäsk > koik.txt 2>&1stdout ja stderr koos