Інші відповіді - це надмірні спрощення, кожна з яких представляє лише частини історії, і помиляються в парах пунктів.
Існує два способи відстеження робочого каталогу:
- Для кожного процесу в структурі даних простір ядра, яка представляє цей процес, ядро зберігає дві посилання vnode на vnode робочого каталогу та кореневу директорію цього процесу. Перше завдання встановлюється з допомогою
chdir()
і fchdir()
системних викликів, останній від chroot()
. Їх можна побічно бачити в /proc
операційних системах Linux або за допомогою fstat
команди на FreeBSD тощо:% fstat -p $$ | голова -n 5
КОРИСТУВАЧ CMD PID FD МОНТАЖ РЕЖИМУ СУМ |
JdeBP zsh 92648 текст / 24958 -r-xr-xr-x 702360 r
JdeBP zsh 92648 ctty / dev 148 crw - w ---- pts / 4 rw
JdeBP zsh 92648 wd / usr / home / JdeBP 4 drwxr-xr-x 124 r
JdeBP zsh 92648 корінь / 4 drwxr-xr-x 35 r
%
Коли роздільна здатність імені працює, воно починається з одного чи іншого із зазначених вузлів, залежно від того, чи шлях відносний чи абсолютний. (Є сімейство …at()
системних викликів, які дозволяють розв’язання імені шляху починатися на vnode, на яку посилається відкритий дескриптор файлу (каталогу), як третій варіант.)
У Microkernel Unices структура даних знаходиться в просторі додатків, але принцип проведення відкритих посилань на ці каталоги залишається тим самим.
- Внутрішньо, в оболонках, таких як оболонка Z, Korn, Bourne Again, C і Almquist, оболонка додатково відслідковує робочий каталог, використовуючи рядкові маніпуляції з внутрішньою змінною рядка. Це робиться кожен раз, коли це викликає причину дзвінка
chdir()
.Якщо змінено відносне ім'я шляху, він маніпулює рядком для додавання цього імені. Якщо один зміниться на абсолютне ім'я шляху, він замінить рядок новим іменем. В обох випадках він налаштовує рядок для видалення .
та ..
компонентів та переслідує символічні посилання, замінюючи їх своїми іменами, пов’язаними з ними. ( Ось , наприклад , код оболонки Z для цього .)
Ім'я у змінній внутрішньої рядка відстежується змінною оболонки з назвою PWD
(або cwd
в оболонках C). Це умовно експортується як змінна середовища (названа PWD
) до програм, породжених оболонкою.
Ці два методи відстеження речей виявлено з допомогою -P
і -L
опцій до cd
і pwd
оболонки вбудованих команд, а також відмінності між оболонками вбудованих pwd
команд і як /bin/pwd
команди і вбудовані pwd
команди речей , як (серед інших) VIM і NeoVIM.
% mkdir a; ln -sab
% (cd b; pwd; / bin / pwd; printenv PWD)
/ usr / home / JdeBP / b
/ usr / home / JdeBP / a
/ usr / home / JdeBP / b
% (cd b; pwd -P; / bin / pwd -P)
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
% (cd b; pwd -L; / bin / pwd -L)
/ usr / home / JdeBP / b
/ usr / home / JdeBP / b
% (cd -P b; pwd; / bin / pwd; принтенв PWD)
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
% (cd b; PWD = / привіт / там / bin / pwd -L)
/ usr / home / JdeBP / a
%
Як бачите: отримання «логічного» робочого каталогу - це питання перегляду PWD
змінної оболонки (або змінної середовища, якщо вона не є програмою оболонки); тоді як отримання «фізичного» робочого каталогу - це питання викликати функцію getcwd()
бібліотеки.
Функціонування /bin/pwd
програми при використанні -L
опції дещо тонке. Він не може довіряти значенню PWD
змінної середовища, яке він успадкував. Зрештою, вона не повинна викликати оболонку, і втручаються програми, можливо, не реалізували механізм оболонки, щоб PWD
середовище змінної завжди відстежувало назву робочого каталогу. Або хтось може робити те, що я робив саме там.
Отож, це робиться (як говорить стандарт POSIX), перевірте, чи вказане ім'я PWD
дає те саме, що і ім'я .
, як це можна побачити з трасуванням системного виклику:
% ln -sac
% (cd b; truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ usr / home / JdeBP / b", { режим = drwxr-xr-x, inode = 120932, розмір = 2, blksize = 131072}) = 0 (0x0)
stat (".", {mode = drwxr-xr-x, inode = 120932, розмір = 2, blksize = 131072}) = 0 (0x0)
/ usr / home / JdeBP / b
% (cd b; PWD = / usr / local / etc truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ usr / local / тощо" , {режим = drwxr-xr-x, inode = 14835, розмір = 158, blksize = 10240}) = 0 (0x0)
stat (".", {mode = drwxr-xr-x, inode = 120932, розмір = 2 , blksize = 131072}) = 0 (0x0)
__getcwd ("/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ usr / home / JdeBP / a
% (cd b; PWD = / hello / там ферми / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ hello / there", 0x7fffffffefe30) ERR # 2 'Немає такого файлу чи каталогу'
__getcwd ("/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ usr / home / JdeBP / a
% (cd b; PWD = / usr / home / JdeBP / c ферми / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ usr / home / JdeBP / c ", {режим = drwxr-xr-x, inode = 120932, розмір = 2, blksize = 131072}) = 0 (0x0)
stat (". ", {Mode = drwxr-xr-x, inode = 120932 , розмір = 2, розмір зображення = 131072}) = 0 (0x0)
/ usr / home / JdeBP / c
%
Як бачите: він дзвонить лише у getcwd()
випадку виявлення невідповідності; і його можна обдурити, встановивши PWD
рядок, який справді називає той самий каталог, але іншим маршрутом.
Функція getcwd()
бібліотеки є предметом сама по собі. Але до précis:
Навігація до ..
- знову ж таки сам предмет. Інший принцип: Хоча умовні каталоги (хоча, як уже згадувалося, це не потрібно) містять фактичну ..
структуру даних каталогів на диску, ядро відслідковує батьківський каталог кожної директорії vnode і, таким чином, може переходити до ..
vnode будь-якого робочий каталог. Це дещо ускладнюється монтовою точкою та зміненими кореневими механізмами, які виходять за рамки цієї відповіді.
Убік
Насправді Windows NT робить подібне. Є один робочий каталог на кожен процес, встановлений SetCurrentDirectory()
викликом API і відслідковується за процесом ядром через (внутрішню) відкриту ручку файлу до цього каталогу; а також існує набір змінних оточуючих середовищ, які програми Win32 (не лише інтерпретатори команд, але й усі програми Win32) використовують для відстеження імен декількох робочих каталогів (по одному на диск), додаючи або перезаписуючи їх щоразу, коли вони змінюють каталог.
Зазвичай, на відміну від операційних систем Unix та Linux, програми Win32 не відображають користувачам ці змінні середовища. Іноді їх можна побачити в Unix-подібних підсистемах, що працюють на Windows NT, а також, використовуючи команди команду інтерпретаторів SET
певним чином.
Подальше читання