Дві точки

скріншот консолі, який рве шаблон

На картинці вище ви можете спостерігати, як ls вважає, що linkylink/.. це не те ж саме, що поточний каталог. При цьому cd, здається, з ним не згоден.

Почну розповідь з усім знайомих веб-адрес, які схожі на системні шляху.

Дві точки в шляхах URI (в інтернеті)
Інтерпретація точок описана в секції 5.2.4 RFC 3986.
Працює це так: кожен сегмент з двох точок знищує попередній сегмент:

/a/b/c/../../g <=> /a/g
при цьому, якщо знищувати нічого, дві точки ігноруються:

example.com/../../../etc/passwd <=> example.com/etc/passwd
Правила були придумані, щоб відносні шляхи (../img/pic.png) можна було перетворювати в абсолютні префіксом з uri-контексту:

  1. /a/css/index.css посилається на ../img/pic.png
  2. /a/css/index.css знищується все після останнього слеша => /a/css/
  3. ../img/pic.png додається до /a/css/ => /a/css/../img/pic.png
  4. точки інтерпретуються => /a/img/pic.png
Ці операції зазвичай робляться браузером, коли він перетворює відносні uri в абсолютні. Також, згідно стандарту, операція знищення точок повинна виконуватися при приведенні uri до каноничному увазі — нормалізації — в тому числі абсолютних uri.

Веб-сервера в дикій природі не стикаються з запитами містять точки і кожен обробляє їх по-своєму.

В цілому, виходячи з правила нормалізації випливає, що в uri виду 'http://example.com/a/b/../c' 'b' не зобов'язана існувати.

Дві точки в шелле
Схожим чином поводиться шелловая команда cd: дві точки завжди ведуть на один сегмент путя вище, як би скасовуючи попередній перехід в підкаталог. Але, на відміну від uri, шелл перевіряє існування проміжних каталогів.

Якщо ви вважаєте перше природним, то ця публікація для вас. Насправді шелл емулює така поведінка cd: у всіх інших місцях *nix ".." працює по-іншому.


Навіть вбудована команда source (або її синонім ".") має відмінну поведінку від cd

Різниця проявляється на символьних посилання на каталоги: для cd перехід за посиланням звернемо через "..", тоді як інша система буде сприймати ".." як фізичної батьків каталогу, на який посилання.

По-іншому перше поведінка називається logical (-L у pwd і cd), в протилежність physical (-P).

Дві точки файлової системи
Взагалі, в *nix ніде не зберігається шлях до робочого каталогу процесу, а замість цього для кожного процесу система запам'ятовує inode (ім'я файлу) поточного і базового каталогів. Коли де-небудь потрібно шлях, він обчислюється послідовними переходами вгору по файловій ієрархії, від поточного каталогу, до кореня, запам'ятовуючи кожен крок.

В *nix ".." — це реальний підкаталог, єдиний фізичний батько, незалежний від символьних посилань. Якщо подивитися всередину файлової системи ext2, то опис підкаталогів ".." і "." нічим не буде відрізнятися від інших, крім того, що вони перераховуються спочатку.

Перехід по деякому шляху — це те ж саме, що послідовний перехід в підкаталоги.

Неважко помітити, що якщо ми потрапили в певний каталог за символьним посиланням, то у нас не залишиться інформації, щоб повернутися: ".." буде вказувати фізичного батька. Але як тоді cd працює з логічними шляхами, що включають в себе симлинки? Для цього шелл запам'ятовує шлях, яким він прийшов в каталог. Логічний шлях, побудований шеллом, доступний через змінну оточення $PWD або через pwd [-L].

Дві точки вимагають уваги, особливо в скриптах.
PS: Символьних посилань на каталоги дуже багато в sysfs:

bug@earth /sys/class/net/lo % ls
addr_assign_type flags phys_port_id
address gro_flush_timeout phys_switch_id
addr_len ifalias power

bug@earth /sys/class/net/lo % ls…
lo
bug@earth /sys/class/net/lo % pwd -P; pwd -L
/sys/devices/virtual/net/lo
/sys/class/net/lo
bug@earth /sys/class/net/lo % cd ..; ls
eth0 lo

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.