Linuks terminal za početnike

Kako nisam pronašao na internetu dobar tutorijal o Linuks terminalu na srpskom jeziku, odlučio sam se da sâm napišem jedan. Tutorijal je podeljen u osam sekcija. Za apsolutne početnike dovoljne su samo prve tri sekcije.

Kretanje po sistemu

Pokrenite svoj preinstalirani terminal. Otvoriće se prozor s tekstom poput sledećeg:

[user@machine ~]$

Tekst na početku linije najčešće čine vaš username, ime vašeg računara i znak tilda (~). Ceo ovaj tekst se naziva prompt.

Unesite sada svoju prvu komandu u prompt: pwd i pritisnite Enter. Naziv ove komande je skraćenica izraza print working directory. Pogledajmo šta se desilo:

[user@machine ~]$ pwd
/home/user
[user@machine ~]$

Komanda je izvršena, naziv direktorijuma (foldera) u kome se nalazite je ispisan, a zatim se ponovo pojavila prompt linija [user@machine ~]$ koja označava da možete uneti narednu komandu. Ispitajmo šta se nalazi u vašem direktorijumu. To možemo učiniti uz pomoć komande ls (list):

[user@machine ~]$ ls
Desktop Download Pictures Documents slika.jpg text.txt 
[user@machine ~]$
Rezultat ls komande može biti različito obojen u zavisnosti od toga da li je reč o direktorijumu, običnoj datoteci, izvršnoj datoteci itd…

Naravno, rezultat komande ls zavisi od sadržaja direktorijuma u kom se nalazite. Mi ćemo kreirati jedan prazan direktorijum test, uz pomoć komande mkdir (skraćeno od make directory):

[user@machine ~]$ mkdir test
[user@machine ~]$

Ako ponovo pokrenemo ls komandu videćemo da se u našem direktorijumu nalazi barem jedan direktorijum, upravo onaj koji smo malopre kreirali.

[user@machine ~]$ ls
test
[user@machine ~]$

Komanda mkdir je napravila direktorijum sa imenom koje smo zadali nakon imena komande. Čest je slučaj da se nakon komande (u istoj liniji) ukucava i ime nekog direktorijuma ili datoteke na koje želimo da ta komanda deluje. Svaku reč koja dolazi nakon imena komande nazivamo argumentom.

Ako želimo da promenimo direktorijum u kom se nalazimo, to možemo učiniti uz pomoć komande cd (change directory). Nakon imena komande navešćemo ime direktorijuma u koji želimo da uđemo.

[user@machine ~]$ cd test
[user@machine test]$

Ukucavanjem pwd komande dobijamo sledeći rezultat:

[user@machine test]$ pwd
/home/user/test

Primetimo da je naziv direktorijuma u kom se nalazimo zamenio tildu u prompt liniji. To se dešava zato što tilda predstavlja home direktorijum svakog korisnika Linuks sistema. Svaki korisnik ima svoj home direktorijum čiji je naziv isti kao ime (username) tog korisnika. Home direktorijumi svih korisnika (osim administratora) nalaze se u direktorijumu /home. Na primer, ako bi korisnici nekog računara bili samo Alisa i Bob, tada bi /home direktorijum sadržao samo direktorijume Alisa i Bob. Sadržaj određenog home direktorijuma može menjati samo vlasnik tog home direktorijuma i administrator sistema.

Ali vratimo se cd komandi. Trenutno se nalazimo unutar test direktorijuma. Ako bismo želeli da se vratimo u svoj home direktorijum, možemo uneti cd komandu sa tildom:

[user@machine test]$ cd ~
[user@machine ~]$

Takođe, ako unesemo cd komandu bez argumenta, vratićemo se uvek u svoj home direktorijum.

[user@machine test]$ cd
[user@machine ~]$

Napravimo sad jedan direktorijum test2 unutar test direktorijuma. To možemo učiniti na dva načina. Možemo prvo ući u test direktorijum a zatim kreirati direktorijum test2. Nije komplikovano, ali može jednostavnije. Dovoljno je samo da navedemo put do direktorijuma koji želimo da kreiramo:

[user@machine ~]$ mkdir test/test2

Ovaj način identifikacije položaja nekog direktorijuma naziva se relativni put (relative path). Postoji takođe i apsolutni put do neke datoteke ili direktorijuma. U prethodnom primeru korišćenje apsolutnog puta bi izgledalo ovako:

[user@machine ~]$ mkdir /home/user/test/test2

Kao što vidite, apsolutni put započinje s kosom crtom i njime možemo označiti bilo koju datoteku ili direktorijum u svom sistemu, dok relativnim putem zasada možemo označiti samo datoteke i direktorijume unutar direktorijuma u kom se trenutno nalazimo.

Oba načina predstavljanja možemo koristiti i sa cd komandom (ili s bilo kojom drugom). Ako želimo da iz svog home direktorijuma pređemo u test2 direktorijum, možemo koristiti relativni put:

[user@machine ~]$ cd test/test2

ili apsolutni put:

[user@machine ~]$ cd /home/user/test/test2

Oba načina će naravno dati isti rezultat, tj. prebaciće nas u test2 direktorijum.

Ako smo dovoljno radoznali, možemo ukucati komandu cd / koja će nas odneti u korenski root direktorijum. U root direktorijumu nalaze se sve datoteke s kojima Linuks sistem raspolaže. Izlistavanjem korenskog direktorijuma dobijamo listu od desetak direktorijuma. Ovo su neki od tih direktorijuma:

[user@machine /]$ ls
/bin   /boot  /dev   /etc   /home  /lib   /media /mnt
/opt   /proc  /root  /sbin  /srv   /tmp   /usr   /var

Unutar root direktorijuma postoji direktorijum s nazivom root (što je ponekad izvor zabune jer se i korenski direktorijum često naziva root, ali ime tog direktorijuma je samo /). Direktorijum /root služi kao home direktorijum administratoru sistema. Ovo je sadržaj ostalih direktorijuma:

Važno: Iako preporučujem čitaocima da pregledaju sadržaj navedenih direktorijuma na svom sistemu, isto tako im preporučujem da ne pokušavaju da na bilo koji način izmene taj sadržaj.

Još malo o komandama

Vratimo se sada u svoj test direktorijum. Napravimo sada jednu praznu datoteku uz pomoć komande touch:

[user@machine test]$ touch datoteka
[user@machine test]$ ls
test2 datoteka

Tri veoma bitne stvari:

  1. Iako je prilikom davanja imena datoteka na Linuks sistemima moguće koristiti gotovo sve karaktere (osim znaka /), preporučljivo je da se koriste samo slova, brojevi, tačka, crtica i donja crta. Život ćete sebi olakšati ako ostanete pri ovim karakterima. Izbegavajte pogotovu razmak, a umesto njega koristite donju crtu.
  2. Prilikom davanja imena datoteka ne morate zadavati ekstenziju (primera radi .txt ili .jpg), jer Linuks sistem ignoriše ekstenzije. Zadavanje ekstenzija će vama pomoći da lakše razlikujete datoteke.
  3. Imena datoteka na Linuks sistemima, za razliku od Windows sistema, osetljiva su na velika i mala slova (case-sensitive), pa tako u jednom direktorijumu istovremeno možemo imati različite datoteke: a.txt, A.txt, A.TXT itd…

Koristeći komandu du (disk usage), možemo se uveriti da datoteka sadrži 0 bajtova:

[user@machine test]$ du datoteka
0 datoteka

Obrišimo sada ovu praznu datoteku koristeći komandu rm (remove):

[user@machine test]$ rm datoteka
[user@machine test]$ ls
test2

Važno: Prilikom korišćenja rm komande uvek imajte na umu da ona zaista uklanja datoteku bez mogućnosti povratka (za razliku od Windowsa gde ste verovatno navikli da obrisane datoteke uvek možete naći u Recycle Binu).

Ako pokušamo da obrišemo i test2 direktorijum koristeći rm komandu, dobićemo sledeću grešku:

[user@machine test]$ rm test2
rm: cannot remove 'test2/': Is a directory

Program rm odbija da obriše direktorijum iz sigurnosnih razloga. Zbog toga mi moramo reći komandi da zaista znamo da se radi o direktorijumu korišćenjem opcije --recursive:

[user@machine test]$ rm --recursive test2

Ovog puta direktorijum, sa svim svojim sadržajem, biće zaista obrisan. Ali, da ne bismo stalno pisali --recursive kad god želimo da obrišemo direktorijum, možemo umesto toga koristiti skraćenu verziju ove opcije:

[user@machine test]$ rm -r test2

Uz svaki program koji se koristi u komandnoj liniji postoji određen skup opcija koji se može navesti kao argument. Većina tih opcija dolazi u punom i u skraćenom obliku (koji se sastoji od samo jednog slova). Pre pisanja punog oblika potrebno je staviti dve crtice, a pre pisanja skraćenog oblika potrebno je staviti jednu crticu. Puni oblici opcija moraju se razdvojiti razmakom i crticama ispred svake opcije, tj. moraju se navesti kao posebni argumenti. Skraćeni oblici se mogu pisati zajedno s jednom crticom ispred svih opcija ili razdvojeno sa crtom ispred svake opcije, tj. mogu se navesti kao jedan ili više argumenata. Redosled navođenja opcija (najčešće) nije bitan.

Na primer, ako neki program ima opcije --opcijaA (skraćeno -a), --opcijaB (skraćeno -b) i --opcijaC (skraćeno -c), tada su sledeće komande jednake:

Kao i sve ostalo u Linuks svetu, opcije su osetljive na velika i mala slova. Naravno, iako neki različiti programi imaju opcije sa istim imenom (ili istim skraćenim imenom što je češći slučaj), te opcije imaju različit uticaj na rad programa. Primer za to su komande rm i ls. Iako obe komande prihvataju opciju -r, u prvom slučaju -r je zamena za --recursive dok u drugom -r je zamena za --reverse.

Kako je broj komandi koji se koristi ogroman, nemoguće je zapamtiti sve opcije koje ti programi podržavaju. Zbog toga na svakom Linuks sistemu postoje uputstva za upotrebu većine programa. Ova uputstva se otvaraju uz pomoć komande man (manual). Ako želimo da pročitamo uputstvo za mkdir komandu, ukucaćemo u prompt man mkdir. U terminalu će se pojaviti sledeći, ili barem veoma sličan, tekst:

NAME
mkdir - make directories
SYNOPSIS
mkdir [OPTION]... DIRECTORY...
DESCRIPTION
Create the DIRECTORY(ies), if they do not already exist.
Mandatory arguments to long options are mandatory for short options too.

-m, --mode=MODE
set file mode (as in chmod), not a=rwx - umask

-p, --parents
no error if existing, make parent directories as needed

-v, --verbose
print a message for each created directory

-Z
set SELinux security context of each created directory to the default type

--context[=CTX]
like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX

--help
display this help and exit

--version
output version information and exit
....
Pomoću strelica možete pomerati tekst po terminalu. Kada završite sa čitanjem man stranice, pritiskom na q se možete vratiti u prompt.

Iz man stranice možemo pročitati mnogo informacija koje nam mogu biti od koristi prilikom rada s komandom. Kratku informaciju o komandi možemo dobiti i korišćenjem komande whatis. Pokušajte da sami otvorite man stranice za komande koje smo do sada spomenuli.

Rad s datotekama

U nastavku teksta će umesto cele prompt linije biti naveden samo dolar znak.

Na početku prethodnog dela naučili smo kako možemo kreirati prazne datoteke uz pomoć komande touch. Sad ćemo upoznati jedan od mnogih načina kako možemo kreirati tekstualnu datoteku unutar terminala uz pomoć komande nano. Pokrenite nano ukucavanjem u terminal nano ime_vase_datoteke.txt i napišite petnaestak redova bilo kakvog teksta (koristeći pritom Enter taster za prelazak u novi red). Taj tekst možete sačuvati pritiskom tastera Ctrl+o. Korišćenjem kombinacije Ctrl+x izađite is nano programa.

Sada imamo tekstualnu datoteku (npr. readme.txt) sa petnaestak redova teksta. Uz pomoć komande du možemo se uveriti da je veličina ove datoteke nekoliko kilobajta. Ako želimo, tu datoteku možemo kopirati u drugi direktorijum korišćenjem komande cp (copy), uz koju moramo navesti ime originalne datoteke, kao i destinaciju na koju želimo da je kopiramo:

$ cp readme.txt /home/user/folder/folder2/

Umesto apsolutnog puta, mogli smo koristiti i relativan put folder/folder2/. Ako bismo želeli da kopija naše datoteke ima drugačiji naziv nego original, dovoljno bi bilo da nakon destinacije navedemo novo ime:

$ cp readme.txt folder/folder2/novo_ime.txt

Ako želimo, možemo kopirati više datoteka istovremeno na istu destinaciju. Pritom se poslednje navedeni put interpretira kao destinacija:

$ cp prvi.txt drugi.txt treci.txt put/do/novog/direktorijuma/

Slično funkcioniše i komanda mv (move) koja pomera datoteku na neku destinaciju.

$ mv readme.txt folder/folder2/

Program mv se često koristi i za preimenovanje datoteka. Pritom pomeramo datoteku u okviru istog direktorijuma, ali joj menjamo naziv:

$ mv readme.txt readme_novo_ime.txt

Komanda mv odnosno cp može se koristiti i za pomeranje i preimenovanje odnosno kopiranje direktorijuma (s tim što je za cp potrebna i opcija --recursive). Prilikom rada sa ovim komandama treba biti pažljiv, jer ako kojim slučajem na željenoj destinaciji postoji datoteka sa istim imenom, tada će ta datoteka biti nepovratno prepisana našom datotekom.

Zanimljivo je da na Linuks sistemu skrivene datoteke i direktorijumi počinju s tačkom. Ako u praznom direktorijumu kreiramo datoteku .readme.txt, a zatim pokušamo da izlistamo sadržaj direktorijuma sa ls, nećemo dobiti nikakav rezultat (isto će se desiti ako kreiramo direktorijum čije ime počinje s tačkom). Zato moramo uz ls komandu upotrebiti opciju --all (skraćeno -a). Ovog puta dobijamo zanimljiv rezultat:

$ touch .readme.txt
$ ls

$ ls --all
. .. .readme.txt

Kao što smo očekivali, vidimo svoju datoteku, ali vidimo da se uz nju u direktorijumu nalaze i dva direktorijuma . i ... Štaviše, ova dva direktorijuma možemo naći u bilo kom direktorijumu. Prvi od njih (.) predstavlja sâm direktorijum u kom se nalazimo, dok drugi (..) predstavlja roditeljski direktorijum. Ako bismo upotrebili komandu cd uz . ušli bismo u isti direktorijum u kom smo do tada i bili, tj. ništa ne bismo promenili. Ako bismo pak pokrenuli cd .. izašli bismo iz direktorijuma u kom smo do tada bili i ušli bismo u roditeljski (parent) direktorijum. To bi izgledalo ovako nekako:

$ pwd
/home/user/folder
$ cd .
$ pwd
/home/user/folder
$ cd ..
$ pwd
/home/user

Ovо možemo iskoristiti da iskačemo iz nekoliko direktorijuma odjednom:

$ pwd
/home/user/folder
$ cd ../..
$ pwd
/home

Na ovaj način, korišćenjem relativnog puta, sada možemo označiti bilo koju datoteku ili direktorijum u sistemu. Do sada smo to mogli uz pomoć apsolutnog puta.

Ako budete radili u terminalu, često ćete poželeti da vidite sadržaj neke tekstualne datoteke bez potrebe za izmenom sadržaja. Naravno, to možete učiniti bilo kojim tekstualnim editorom (npr. nano), ali isto možete učiniti i komandom cat (concatenate). Ovaj program ispisaće sadržaj cele datoteke u terminal.

Ponekad ipak nije potrebno ispisivati celu datoteku, posebno ako je ona dugačka, već je dovoljno ispisati prvih nekoliko redova. Tada se koristi komanda head koja ispisuje prvih 10 redova datoteke. Analogno tome, postoji komanda tail koja ispisuje poslednjih 10 linija neke datoteke. Pročitajte man stranice ovih dveju komandi da biste saznali kako možete promeniti broj 10, i kako možete ispisati sve linije tekstualne datoteke osim prvih (tj. poslednjih) n linija.

Osnovne informacije o datoteci možemo dobiti i korišćenjem programa file. On je posebno koristan prilikom rada s datotekama koje nisu tekstualne (poput slika, muzike, izvršnih fajlova itd…).

Za lociranje datoteka i direktorijuma unutar sistema možete koristiti program find.

Džokeri

Kako pisanje mnogo komandi može biti veoma zamorno, uveden je koncept džokera (wildcard). Džokeri nam omogućavaju da izvršimo istu komandu nad više datoteka i direktorijuma istovremeno.

Primera radi, zamislimo da se nalazimo u direktorijumu s mnogo .mp3 i .jpg datoteka i želimo da uklonimo sve .mp3 datoteke. To možemo jednostavno učiniti koristeći džoker *. Ovaj džoker zamenjuje nula ili više karaktera:

$ rm *.mp3

Argument rm komande u ovom slučaju znači da ta komanda treba da deluje na sve one datoteke čije se ime završava sa .mp3. Slično tome, ako želimo da obrišemo sve datoteke koje počinju s velikim slovom A, unećemo sledeću komandu:

$ rm A*

Moguće je ostaviti samo zvezdicu i obrisati sve neskrivene datoteke i direktorijume u direktorijumu u kom se nalazite:

$ rm *

Naravno, džokeri se mogu koristiti i sa ostalim osnovnim komandama (mv, cp, ls, cat…), i njihovim opcijama. Sledeći primer će premestiti sve .mp3 datoteke koje počinju sa slovom A, u željeni direktorijum:

$ mv A*.mp3 /put/do/direktorijuma

Osim zvezdice postoje još dva džokera:

Detaljnu dokumentaciju o džokerima možete dobiti ukucavanjem komande man 7 glob.

Važno: Kao što je ranije napomenuto, prilikom korišćenja rm komande uvek imajte na umu da ona zaista uklanja datoteku bez mogućnosti povratka. Zato je dobro da pre pokretanja rm sa izrazom koji uključuje džokere, prvo pokrenete ls komandu sa istim izrazom. Tako ćete prvo dobiti listu svih imena koja zadovoljavaju dati izraz.

Tehnike iznete u dosadašnjem tekstu dovoljne su za osnovno snalaženje unutar terminala. Sledeće teme opisuju naprednije (i korisnije) tehnike rada u terminalu. Svako ko želi da nastavi sa čitanjem teksta trebalo bi prvo da savlada do sada iznete tehnike.

Shell

Sada ćemo videti kako komandna linija funkcioniše. Program koji ste pokrenuli na samom početku ovog tutorijala, spada u grupu virtualnih terminala ili kraće samo terminala. Terminal je program koji posreduje između korisnika računara i programa zvanog shell (ljuska). Korisnik računara uz pomoć tastature unosi podatke (komande) u terminal. Kada korisnik pritisne Enter, unetu liniju (ili linije) terminal prenosi do shell-a koji zatim interpretira unete podatke i vraća povratne informacije terminalu. Terminal zatim te informacije ispisuje. Prema tome, shell ima mnogo važniju ulogu od terminala. Odnos korisnika, terminala, shell-a i programa prikazan je na sledećem dijagramu:

Korisnik Terminal Shell Program

Na primer, kada unesete cp tekst.txt ../destinacija/ i pritisnete Enter, terminal taj red prosleđuje shell-u. Shell prvu reč linije interpretira kao ime programa koji želite da pozovete. Shell zatim poziva cp program (ako takav program postoji), prosleđujući mu dva argumenta: tekst.txt i ../destinacija/. U slučaju da nije došlo do greške, cp će početi s kopiranjem. U suprotnom, ako je došlo do greške (npr. zato što navedena datoteka ne postoji), shell će proslediti poruku o grešci u terminal. Kada program cp završi kopiranje, shell prikazuje prompt i spreman je za unos nove komande.

Zamislimo sada sledeću situaciju. U vašem home direktorijumu imate datoteku u čijem nazivu se nalazi razmak. Na primer, neka je to datoteka slika sa mora.jpg. Ako pokušate da kopirate tu sliku uz pomoć komande cp slika sa mora.jpg ~/mojeSlike, dobićete sledeću grešku:

cp: cannot stat slika: No such file or directory
cp: cannot stat sa: No such file or directory
cp: cannot stat mora.jpg: No such file or directory

Shell svaku novu reč (niz karaktera ograničen belinama) interpretira kao novi argument. Prema tome, shell je u prethodnom primeru prosledio programu četiri argumenta umesto dva, i cp program je pokušao da kopira datoteke čija se imena nalaze u prva tri argumenta, na destinaciju zadatu sa četvrtim argumentom.

Da bismo sprečili takvo ponašanje, možemo koristiti kose crte ispred razmaka: cp slika\ sa\ mora.jpg ~/mojeSlike; ili duple navodnike: cp "slika sa mora.jpg" ~/mojeSlike.

U gornjem primeru shell je izvršio još jedan mali trik: Znak tilde ~ zamenio je našim home direktorijumom, tako da je program cp primio /home/user/mojeSlike kao drugi argument.

Shell takođe vrši globing, tj. primenu džokera. Kada do shella stigne linija poput rm *.mp3, tada shell sastavlja listu svih imena koje zadovoljavaju dati opis, a zatim poziva jedan rm program, prosleđujući mu svaki član liste kao poseban argument. Prema tome, pozvani programi nemaju dodira sa džokerima. Bitan detalj je taj da shell poziva program samo jednom. Ako neki program koristi samo prvi argument, a sve ostale ignoriše, on će prilikom korišćenja džokera biti izvršen samo na jednoj datoteci.

Međutim, shell nije zadužen za interpretaciju opcija koje se zadaju nekom programu. Ako se pokrene komanda ls --all, program ls će primiti kao prvi argument upravo --all. Na programu ostaje kako će se ponašati s dobijenom opcijom.

Shell program nije jedinstven, već postoji nekoliko desetina programa koji se mogu koristiti kao shell. Najpoznatiji shell je Bash i velika je verovatnoća da ste do sada radili baš u njemu. Osim bash shella, popularni su i zsh, csh, fish, sh… Da biste videli koji su shell programi instalirani na vašem sistemu, pokrenite chsh (change shell) komandu sa --list-shells opcijom. Istim programom možete promeniti svoj podrazumevani shell.

Bash shell ima još nekoliko zanimljivih trikova: ekspanzija aritmetičkih izraza i supstitucija komandi. Da bismo ih demonstrirali, koristićemo program echo koji štampa u terminal tekst koji mu je prosleđen kao argument.

$ echo Ovo je tekst
Ovo je tekst

Ekspanzija aritmetičkih izraza dozvoljava korisniku da izvršava celobrojne aritmetičke operacije u shell-u. Aritmetička ekspanzija funkcioniše tako što se matematički izraz sačinjen od celobrojnih konstanti, zagrada i osnovnih aritmetičkih operatora (+, -, *, **, /, %) navede unutar izraza $(( )). Sav račun se vrši sa celobrojnim vrednostima.

$ echo $((5**2+2))
27
$ echo Pet podeljeno sa dva je $((5/2)) sa ostatkom $((5%2)).
Pet podeljeno sa dva je 2 sa ostatkom 1. 

Supstitucija komandi dozvoljava postavljanje povratne vrednosti neke komande, za argument neke druge komande. Komandu čiju povratnu vrednost želimo da prosledimo, navodimo unutar izraza $( ).

$ ls
Desktop    Pictures    slika.jpg 
Download   Documents   text.txt
$ echo $(ls)
Desktop Download Pictures Documents slika.jpg text.txt
$ rm -v $(ls)
removed 'slika.jpg'
removed 'text.txt'

Primetimo da echo komada uklanja sve suvišne beline, tj. uklanja formatiranje teksta. Da bismo sačuvali formatiranje, potrebno je koristiti dvostruke ili jednostruke navodnike.

Razlika između dvostrukih i jednostrukih navodnika je u njihovom odnosu prema specijalnim karakterima. Specijalni karakteri su:

~ ` # $ & * ( ) / \ | [ ] { } ; ' " < > ? !

U izrazu koji se nalazi između dvostrukih navodnika, svi specijalni karakteri shella se ignorišu osim karaktera \, $ i '. U izrazu koji se nalazi unutar jednostrukih navodnika svi specijalni karakteri se ignorišu.

U oba slučaja sve beline se čuvaju, a ceo izraz se prenosi kao jedna reč. Ovo je demonstrirano na početku ove glave u primeru s kopiranjem datoteke koja sadrži belinu u svom nazivu.

U praksi, ignorisanje specijalnih karaktera podrazumeva potiskivanje mehanizama poput džokera ili zamene tilde, ali ne i potiskivanje aritmetičke ekspanzije i supstitucije komandi (zato što ova dva mehanizma koriste karakter $). Jednostruki navodnici potiskuju sve navedene mehanizme.

$ ls 
Desktop    Pictures   slika.jpg 
Download   Documents   text.txt
$ echo $(ls) 
Desktop Download Pictures Documents slika.jpg text.txt
$ echo "$(ls)"
Desktop    Pictures   slika.jpg
Download   Documents  text.txt
$ echo '$(ls)'
$(ls)

Većina specijalnih karaktera obrađena je u dosadašnjem tekstu. Ovo su pojašnjenja za neke od preostalih karaktera:

Karakter # služi za označavanje komentara. Sve što se nalazi u liniji nakon ovog karaktera, ignoriše se.

Karakter ; služi za razdvajanje komandi. On omogućuje da se u jednoj liniji napiše više komandi.

Karakter \ ispred bilo kog specijalnog karaktera poništava njegovo specijalno značenje. Osim toga, kombinacije poput \ , \n i \t označavaju respektivno belinu, novi red i tabulator.

$ rm *    # Briše sve datoteke u trenutnom direktorijumu
$ rm \*   # Briše datoteku *
$ echo "Tekst\nu\nviše\nredova"
Tekst
u
više
redova

Upravljanje procesima

Linuks sistem, kao i svi moderni operativni sistemi, dozvoljava multitasking tj. istovremeno izvršavanje više programa (procesa). Shell takođe dozvoljava multitasking, iako to na prvi pogled ne izgleda tako. Ova sekcija je posvećena upravljanjem procesa uz pomoć shella.

U narednim primerima koristićemo komandu sleep kao zamenu za bilo koji program čije izvršavanje dugo traje. Komanda sleep jednostavno spava, tj. ne radi ništa, tačno onoliko sekundi koliko smo joj zadali argumentom (sleep 10 spava tačno deset sekundi itd…).

Ako želimo da neku komandu pokrenemo i odmah da oslobodimo prompt, potrebno je da komandu završimo znakom &. Tada će ta komanda nastaviti svoj rad u pozadini shella (background), a nama će prompt biti slobodan za nove komande:

$ sleep 20 &
[1] 1486

$ 

Shell će prilikom prebacivanja procesa u pozadinu odštampati u terminal dva broja. Oba broja služe za identifikaciju procesa. Broj u uglastim zagradama naziva se job number, dok se broj pored njega naziva process ID (PID). Job number služi za identifikaciju procesa unutar jednog shella, dok process ID služi za identifikaciju procesa unutar celog sistema. Process ID je jedinstven za svaki pokrenuti proces na računaru.

Da bismo povratili proces iz pozadine, iskoristićemo komandu fg (foreground), navodeći kao argument job number. Pritom će shell odštampati ime procesa koji smo povratili.

$ fg 1
sleep 20 &

Ako ne želimo da pamtimo job number za svaki proces u pozadini, možemo iskoristiti komandu jobs. U narednom primeru pokrenuto je nekoliko procesa u pozadini, a zatim je pokrenut jobs program.

$ sleep 120 &
[1] 5642

$ sleep 140 &
[2] 5649

$ sleep 160 &
[3] 5655

$ jobs 
[1]  Running sleep 120 &
[2]- Running sleep 150 &
[3]+ Running sleep 160 &
Plus i minus označavaju poslednja dva procesa koja su postavljena u pozadinu.

Naravno, shell je sposoban da upravlja mnogo većim brojem programa istovremeno. Svaki od tih programa može se dovesti u prvi plan uz pomoć komande fg.

Nakon što program završi s radom u pozadini, prilikom prvog pritiska tastera Enter u terminalu će se pojaviti poruka koja obaveštava korisnika da je program prestao s radom.

$ sleep 20 &
[1] 7655

$
$ 
[1]+ Done sleep 20 &

Možemo neki proces postaviti u pozadinu iako smo ga prethodno pokrenuli bez ampersanda na kraju, tako što ćemo nakon pokretanja procesa pritisnuti Ctrl+z. U tom slučaju proces koji se trenutno nalazi u prvom planu pauzira se i postavlja se u pozadinu, a prompt se oslobađa za nove komande. Da bismo pokrenuli pauziran program u pozadini, dovoljno je da pokrenemo bg komandu sa job number-om kao argumentom.

$ sleep 120
$ #U ovom trenutku ste pritisnuli Ctrl-z
$ jobs 
[1]+ Stopped sleep 120 &

$ bg %1
$ jobs 
[1]+ Running sleep 120 &

Ako želimo da prekinemo rad programa u pozadini iskoristićemo kill komandu, navodeći kao argument PID ili job number programa koji želimo da prekinemo. Ipak, kill komanda radi više od prostog ubijanja programa. Ona šalje programima različite signale. POSIX standardima je predviđeno tridesetak različitih signala, koji imaju različite efekte na programe. Svaki signal se označava svojim brojem ili kratkim imenom. U narednoj tabeli dati su signali koji se najčešće mogu sresti prilikom rada s programima (Prazne ćelije u prvoj koloni označavaju da ti signali nemaju standardizovane brojeve).

Broj Naziv Pun naziv Opis
1 SIGHUP Hungup signal Šalje se programu kada korisnik zatvori terminal u kom je program pokrenut. Program može ignorisati ovaj signal.
2 SIGINT Interrupt signal Ovaj signal se može poslati i pritiskom Ctrl+c dok je program u prvom planu. Program bi pri primanju ovog signala trebalo da prekine s trenutnom operacijom, i sačeka naredne instrukcije korisnika. Program može ignorisati ovaj signal.
9 SIGKILL Kill signal Ovaj signal dovodi do prekida rada programa. Program ne može ignorisati ovaj signal.
15 SIGTERM Termination signal Program bi pri primanju ovog signala trebalo da prestane s radom. Program može ignorisati ovaj signal.
SIGTSTP Terminal stop signal Program koji primi ovaj signal staje (privremeno) s radom. U terminalu, pritiskom Ctrl+z, programu u prvom planu će biti poslat ovaj signal i on će biti stavljen u pozadinu. Program može ignorisati ovaj signal.
SIGSTOP Stop signal Slično kao prethodni signal, ovaj signal zaustavlja rad programa. Međutim, ovaj signal program ne može ignorisati.
SIGCONT Continue signal Program koji primi ovaj signal nastavlja s radom ako je do tada bio stopiran.

Komanda kill može slati signale bilo kom pokrenutom programu u operativnom sistemu. Da bismo videli listu svih pokrenutih programa, možemo iskoristiti komandu ps sa opcijom x. Bez ove opcije ps će prikazati samo procese koji su pokrenuti iz trenutnog terminala. Sa opcijom x, komanda ps prikazuje sve aktivirane procese. Obratite paznju na to da se opcija x u ovom slučaju navodi bez crtice.

Da bi ovo sve bilo jasnije, prikažimo jedan primer. Zamislimo da je editor teksta gedit prestao da odgovara na komande (popularno rečeno, zapucao se), dok ostatak sistema u potpunosti funkcioniše. Tada mi možemo otvoriti jedan terminal, i uz pomoć komande ps identifikovati PID programa gedit (neka je to na primer 2531). Nakon toga, pozvaćemo komandu kill 2531. Program kill tada šalje signal SIGTERM geditu. Gedit bi tada trebalo da sâm uredno prekine svoj rad. To najpre podrazumeva snimanje nesačuvanog rada na hard disk, oslobađanje zauzete radne memorije itd… Ako gedit nije u stanju da odgovori na SIGTERM, tada mi možemo poslati signal SIGKILL. Operativni sistem će registrovati ovaj signal, i prinudno će zaustaviti gedit program. Signal SIGKILL sigurno zaustavlja svaki pokrenuti program, ali njegovom primenom može doći do raznih neprijatnih posledica (npr. gubitak nesačuvanog rada itd…).

Upravljanje procesima moguće je izvršiti i uz pomoć top programa. Program top na interaktivan način prikazuje u terminalu spisak pokrenutih procesa, resurse koje ti procesi koriste, resurse kojima sistem raspolaže itd… (nešto poput Task Manager-a na Windows sistemima).

Redirekcija

Prilikom pokretanja svakog programa, shell otvara i tri toka podataka: standardni ulaz (STDIN), standardni izlaz (STDOUT) i standardni izlaz za greške (STDERR). Uz pomoć ovih tokova, svaki program može da čita i piše podatke, kao i da ispisuje greške. Podrazumeva se da će kroz ove tokove prolaziti tekstualne informacije.

Program STDIN STDOUT STDERR
Šematski prikaz standardnih tokova.

Shell po defaultu usmerava ova tri toka na terminal, što znači da sve što program piše u STDOUT i STDERR tokove, ispisuje se u terminal, i sve što program čita iz STDIN toka, čita se iz terminala. Ipak, ponekad je korisno preusmeriti ove tokove tako da program čita ili upisuje podatke u neku datoteku, ili preusmeriti izlaz jednog programa ka ulazu drugog. To se postiže uz pomoć narednih operatora:

Na primer, ako želimo da rezultat ls komande sačuvamo u datoteci sadrzaj.txt, tada možemo pokrenuti komandu ls > sadrzaj.txt. Ako želimo da izbrojimo broj reči u tekstualnoj datoteci text.txt tada možemo iskoristiti program wc (word count), kome ćemo proslediti sadržaj datoteke text.txt na sledeći način: wc < text.txt. Navedene operatore možemo kombinovati, pa tako rezultat wc programa možemo nadovezati na kraj datoteke broj.txt:

$ wc < text.txt >> broj.txt	

Verovatno najkorisniji od svih navedenih operatora je pipe |. Kao što je rečeno, pipe služi za usmeravanje izlaza jednog programa ka ulazu drugog programa. Moguće je istovremeno korišćenje više pipe-ova. Treba imati na umu da se argumenti programa navode između uspravnih crta.

$ program1 --arg11 --arg12 | program2 --arg2 | program3 --arg3
program1 program2 program3 STDIN 1 STDOUT 3
Šematski prikaz korišćenja pipe-ova.

Naravno, moguće je kombinovanje pipe-ova sa ostalim operatorima redirekcije. Na primer, prilikom pokretanja sledeće linije, sadržaj datoteke input.txt biće prosleđen programu program1, a povratna vrednost programa program2 biće upisana u datoteku output.txt.

$ program1 | program2 <input.txt >output.txt 

Programi koji se koriste sa pipe-ovima nazivaju se filteri. U narednoj tabeli navedeni su neki od najznačajnijih filtera (neki od njih su već opisani u prethodnim redovima).

Naziv Opis
awk Moćan programski jezik namenjen obradi tokova.
cut Odstranjuje određene delove teksta.
grep Ispisuje linije teksta koje zadovoljavaju određen regularan izraz (regex). Uz pomoć grepa moguće je vršiti običnu pretragu neke reči u tekstu.
head Ispisuje početak teksta (prvih 10 linija).
nl Ispisuje tekst s brojevima linija.
sed Zamenjuje određene izraze drugim izrazima.
sort Sortira linije teksta.
tac Ispisuje tekst u obrnutom redosledu.
tail Ispisuje kraj teksta (poslednjih 10 linija).
tr Zamenjuje određene karaktere drugim karakterima. sed je zamena za ovaj filter.
uniq Uklanja linije koje se pojavljuju u tekstu.
wc Broji linije i reči u tekstu.

Gorenavedeni opisi filtera su nepotpuni. Za potpuno razumevanje ovih programa potrebno je pročitati njihove dokumentacije. U nastavku je navedeno par jednostavnijih primera koji ilustruju primenu filtera i redirekcija.

# Spajanje svih datoteka u jednu
cat * > merge.txt

# Ispis 10 najvećih datoteka i direktorijuma
du . | sort -r -n | head -10

# Ispis jedinstvenih reči koje se pojavljuju u datoteci text.txt
tr -c a-zA-Z '\n' < text.txt | sed '/^$/d' | sort | uniq -i -c

# Ispis svih procesa čiji naziv sadrži reč java
ps aux | grep java

Prilikom pisanja pipeline-ova, preporučljivo je nadovezivati jedan po jedan pipe. Na taj način se lako uočavaju potencijalni problemi.

Korisnici i dozvole

Linuks sistem dozvoljava da na njemu istovremeno radi više korisnika. Korisnik koji želi da koristi određen računar s Linuksom, mora posedovati svoj korisnički nalog na tom računaru, koji podrazumeva jedinstveno ime, istoimeni direktorijum u /home direktorijumu, i šifru.

Na svakom Linuks sistemu postoji administrator root koji ima kompletnu kontrolu nad celim sistemom. Ostali korisnici imaju tek kontrolu nad svojim home direktorijumom (osim ako im administrator ne dodeli neke veće dozvole). Svaki od korisnika pripada jednoj ili više grupa, koje svojim članovima daju neke određene dozvole. Administrator sistema je taj koji kontroliše korisnike, grupe i njihove dozvole.

Datotekama i direktorijumima na Linuksu dodeljene su informacije o pravu pristupa, koje podrazumevaju informaciju o tome ko i kako može da pristupi datoteci, odnosno direktorijumu. Postoje tri vrste pristupa datoteci ili direktorijumu:

  1. rread – čitanje datoteke, odnosno listanje direktorijuma.
  2. wwrite – upis u datoteku, odnosno izmena direktorijuma.
  3. xexecute – izvršavanje datoteke, odnosno ulazak u direktorijum.

Svako od ova tri prava definiše se za tri klase: korisnika vlasnika datoteke, grupu vlasnika datoteke, i ostale korisnike. Da bismo videli sve ove informacije za neku određenu datoteku, dovoljno je da pokrenemo ls -l ime_datoteke.

$ ls -l slika_sa_mora.jpg
-rw-r----- 1 john users 3.7K Jun 7 08:22 slika_sa_mora.jpg

Prva kolona u izlazu ls -l komande sastoji se od deset karaktera. Prvi karakter označava da li se radi o datoteci - ili direktorijumu d. Ostalih devet karaktera redom označavaju prava pristupa za korisnika vlasnika datoteke, grupu vlasnika datoteke, i ostale korisnike. Ako je neko pravo pristupa onemogućeno, tada se na njegovom mestu pojavljuje -, a u suprotnom r, w ili x, u zavisnosti od toga koje pravo pristupa je u pitanju.

Druga kolona označava broj direktorijuma unutar datog direktorijuma (ako je u pitanju datoteka, onda se u ovoj koloni nalazi jedinica). Naredne dve kolone označavaju korisnika vlasnika datoteke i grupu vlasnika datoteke. Zatim slede kolone koje označavaju veličinu, vreme poslednje izmene i ime datoteke.

U gornjem primeru vidimo da datoteka slika_sa_mora.jpg pripada korisniku john i grupi users. Korisnik john može da čita i piše u ovu datoteku (rw-), dok ostali korisnici iz grupe users mogu samo da je čitaju (r--). Ostali korisnici nemaju nijedno pravo pristupa ovoj datoteci (---).

Prava pristupa neke datoteke mogu se promeniti uz pomoć programa chmod. Za argumente se navode numerički opis prava pristupa i put do datoteke. Numerički opis podrazumeva da se pravu pristupa dodeli jedan neoznačeni trocifreni oktalni broj. Cifre odgovaraju klasama korisnika: prva cifra odgovara pravima vlasnika, druga cifra pravima grupe, a treća cifra odgovara pravima ostalih korisnika. Ako karaktere r, w i x interpretiramo kao jedinice, a karakter - kao nulu, tada za svaku navedenu klasu korisnika imamo po jedan trocifren binarni broj. Prevođenjem ovog broja u oktalni sistem dobijamo odgovarajuću cifru za klasu korisnika.

U gornjem primeru, kombinacije rw-, r-- i --- odgovaraju respektivno brojevima 110, 100 i 000, tj. oktalnim ciframa 6, 4 i 0. Dakle, numerički opis prava rw-r----- je 640. Ako bismo želeli da omogućimo i ostalim korisnicima da čitaju datoteku slika_sa_mora.jpg, dovoljno bi bilo da pokrenemo chmod 644 slika_sa_mora.jpg.

Promenu prava pristupa datoteke mogu da izvrše vlasnik datoteke i administrator sistema. Prava pristupa se nikad ne odnose na administratora sistema. Administrator može pristupati svim datotekama i direktorijumima na sistemu.

Vlasnik datoteke, i grupa kojoj pripada datoteka, mogu se promeniti uz pomoć programa chusr i chgrp. Ove promene može da izvrši samo administrator sistema.

Kraj

Ovde se ovaj tutorijal završava. U njemu je navedeno i više nego dovoljno informacija potrebnih za početno snalaženje u terminalu. Naredni koraci u savladavanju terminala podrazumevaju učenje basha kao programskog jezika, i detaljnije upoznavanje s Linuks arhitekturom. Zainteresovani čitaoci će lako naći obilje resursa na internetu o ovim temama.