Apsolutne i relativne putanje — ., .., ~, -

Svaka komanda koja dodiruje neki fajl mora da zna gde se taj fajl nalazi. Putanja je odgovor na to pitanje. Postoje samo dve vrste putanja, a razlika između njih staje u jedno pravilo:

Ako putanja počinje kosom crtom, apsolutna je. Ako ne počinje, relativna je i računa se od direktorijuma u kome se trenutno nalaziš.

Sve ostalo u ovoj lekciji su posledice tog pravila.

Odakle se broji: tekući direktorijum

Relativna putanja nema smisla bez polazne tačke. Ta tačka je tekući direktorijum, a proveravaš ga komandom pwd:

$ pwd
/home/alen/dokumenti

Ista relativna putanja znači različite stvari u zavisnosti od toga gde stojiš — i to je i njena prednost i njena zamka.

Za primere u nastavku pretpostavimo ovakvo stablo:

/home/alen
├── dokumenti
│   ├── izvestaj.odt
│   └── arhiva
│       └── stari-izvestaj.odt
├── slike
│   └── odmor.jpg
└── skripte
    └── backup.sh

Apsolutna putanja

Počinje od korena sistema, koji se piše kao /, i nabraja svaki nivo do cilja:

$ cat /home/alen/dokumenti/izvestaj.odt
$ ls /etc/ssh
$ /usr/bin/python3 --version
Python 3.12.3

Apsolutna putanja radi isto iz bilo kog direktorijuma. Nije bitno gde stojiš — /etc/hosts je uvek isti fajl.

Zapamti: prva kosa crta je koren sistema, a sve ostale su samo razdvajači između imena. Zato /home/alen ima dva nivoa, a ne tri. Šta je koji direktorijum u korenu, piše na stranici Direktorijumi i fajlovi Linux sistema.

Relativna putanja

Kreće od mesta na kom si:

$ pwd
/home/alen

$ cat dokumenti/izvestaj.odt
$ ls slike

Nema početne kose crte, pa shell podrazumeva „od ovde". Zato ova ista komanda iz drugog direktorijuma ne radi:

$ cd /tmp
$ cat dokumenti/izvestaj.odt
cat: dokumenti/izvestaj.odt: No such file or directory

Poruka ne znači da fajl ne postoji — znači da ne postoji na tom mestu u odnosu na /tmp.

Tačka i dve tačke

Svaki direktorijum na Linuxu sadrži dva skrivena unosa, i vidiš ih sa ls -a:

$ ls -a
.  ..  izvestaj.odt  arhiva
  • . — ovaj direktorijum, onaj u kom se nalazim
  • .. — direktorijum iznad, roditeljski

Nisu trik u shell-u nego stvarni unosi na disku, i zato rade svuda gde i obično ime.

$ pwd
/home/alen/dokumenti

$ cd ..
$ pwd
/home/alen

Više .. se nadovezuje. Ovako se, iz jednog direktorijuma, kopira u drugi „sa strane":

$ pwd
/home/alen/dokumenti/arhiva

$ cp stari-izvestaj.odt ../../slike/
$ ls ../../slike
odmor.jpg  stari-izvestaj.odt

Prvi .. vodi u dokumenti, drugi u alen, pa se odatle silazi u slike. O samoj komandi ima više na stranici cp.

U korenu sistema .. pokazuje na sam koren — iznad / nema ničega:

$ cd /
$ cd ..
$ pwd
/

Zašto se piše ./skripta.sh

Ovo je najčešće mesto na kome . zatreba:

$ pwd
/home/alen/skripte

$ backup.sh
bash: backup.sh: command not found

$ ./backup.sh
Backup zavrsen.

Kad kucaš golo ime, shell ga traži isključivo u direktorijumima navedenim u promenljivoj PATH. Tekući direktorijum tu namerno nije — da neko ne bi u /tmp ostavio fajl imenom ls i sačekao da ga pokreneš. Tačka i kosa crta govore „ne traži po sistemu, ovaj fajl, tu gde sam".

Tilda: prečica do kućnog direktorijuma

~ shell zamenjuje putanjom do tvog kućnog direktorijuma:

$ echo ~
/home/alen

$ cd ~/dokumenti
$ pwd
/home/alen/dokumenti

Golo cd bez ičega radi isto — vraća te kući, odakle god da kreneš.

Tilda sa imenom pokazuje na tuđi kućni direktorijum:

$ echo ~root
/root
$ echo ~marko
/home/marko

Važno: ~ proširuje shell, isto kao džokere iz lekcije Džokeri i navodnici. Zato prestaje da radi čim je staviš pod navodnike:

$ echo "~"
~
$ cd "~"
bash: cd: ~: No such file or directory

Ako putanja ima razmak, navodnici idu samo oko dela posle tilde:

$ cd ~/"moji dokumenti"

I još jedna posledica istog pravila, koja ume da zbuni:

$ sudo cp izvestaj.odt ~

Ovo ne kopira u /root. Tvoj shell je razrešio ~ u /home/alen pre nego što je href="/2023/10/sudo.html">sudo

uopšte pokrenut. Ako ti stvarno treba rootov kućni direktorijum, napiši /root otvoreno.

Crtica: nazad odakle si došao

cd - te vraća u prethodni direktorijum i usput ispiše gde si stigao:

$ pwd
/home/alen/skripte

$ cd /var/log
$ pwd
/var/log

$ cd -
/home/alen/skripte

Ponovljeno cd - te vrti između te dve lokacije. Neprocenjivo je kad upoređuješ konfiguraciju duboko u /etc sa nečim u svom projektu. Shell prethodnu lokaciju čuva u promenljivoj OLDPWD:

$ echo $OLDPWD
/var/log

Mešanje je dozvoljeno

Komande primaju obe vrste putanja u istoj liniji, i redosled nije bitan:

$ pwd
/home/alen/dokumenti

$ cp izvestaj.odt /tmp/
$ cp /etc/hosts ./arhiva/

Prva kopira relativni izvor na apsolutno odredište, druga obrnuto.

Kad koristiti koju

Pravilo koje se retko izneveri:

  • Relativne — dok radiš rukom u terminalu. Kraće su i brže se kucaju.
  • Apsolutne — u svemu što se izvršava bez tebe: skripte, cron poslovi, systemd servisi, konfiguracioni fajlovi.

Razlog je jednostavan. Skripta ne nasleđuje direktorijum iz koga si je pisao, nego onaj iz koga je pokrenuta. Ovo radi savršeno dok testiraš:

#!/bin/bash
tar -czf backup.tar.gz dokumenti/
$ cd /home/alen
$ ./skripte/backup.sh
$ ls backup.tar.gz
backup.tar.gz

A onda ista skripta iz crona ili iz drugog direktorijuma:

$ cd /tmp
$ /home/alen/skripte/backup.sh
tar: dokumenti/: Cannot open: No such file or directory
tar: Exiting with failure status due to previous errors

Skripta se izvršila u /tmp, gde dokumenti/ ne postoji. Ispravka je da putanje budu apsolutne:

#!/bin/bash
tar -czf /home/alen/backup.tar.gz /home/alen/dokumenti/

Ovo je jedan od najčešćih razloga zašto skripta koja „radi kad je pokrenem ručno" zataji u cronu.

Sitnice koje ume da zabole

Kosa crta na kraju odredišta

$ cp izvestaj.odt /tmp/rezerva/

Ako rezerva ne postoji, komanda prijavi grešku — što je i dobro. Bez kose crte na kraju, cp bi ćutke napravio fajl imenom rezerva. Navika da odredišni direktorijum uvek završiš sa / te čuva od tog tihog promašaja.

Dodatne kose crte se ignorišu

$ ls /home//alen///dokumenti
izvestaj.odt  arhiva

Nije greška, samo ružno. Korisno je znati kad sastavljaš putanje u skriptama, pa se negde nakupi duplo /.

Putanja koja ne ide najkraćim putem

/home/alen/dokumenti/../slike je ista lokacija kao /home/alen/slike. Ako ti treba čist, skraćen oblik, tu je realpath:

$ realpath ../slike/odmor.jpg
/home/alen/slike/odmor.jpg

Zgodno kad treba da prekopiraš tačnu putanju negde u konfiguraciju.

Kratka referenca

  • /putanja — apsolutna, od korena sistema
  • putanja — relativna, od tekućeg direktorijuma
  • . — ovaj direktorijum
  • .. — direktorijum iznad
  • ~ — moj kućni direktorijum
  • ~korisnik — kućni direktorijum drugog korisnika
  • cd — nazad kući
  • cd - — nazad u prethodni direktorijum
  • ./fajl — pokretanje fajla iz tekućeg direktorijuma

Vežba

Napravi stablo iz uvoda:

$ mkdir -p ~/vezba/{dokumenti/arhiva,slike,skripte}
$ cd ~/vezba/dokumenti/arhiva
$ touch stari.odt ../izvestaj.odt ../../slike/odmor.jpg

Iz direktorijuma arhiva, bez upotrebe cd i bez pisanja /home, uradi sledeće:

  1. izlistaj sadržaj direktorijuma slike
  2. kopiraj stari.odt u skripte
  3. ispiši punu apsolutnu putanju do odmor.jpg

Za treći zadatak dovoljni su realpath i ono što već znaš o ...


Sad kad znaš da se krećeš i da opišeš gde je šta, sledi šta se sa tim fajlovima može raditi: Rad sa fajlovima i direktorijumima.

Cela lekcija je deo vodiča Linux osnove.

Comments

Popular posts from this blog

Početak u Linuxu — šta je i zašto se uči

Konverzija tipova podataka u Pythonu

groupadd