Unix программные ссылки и пути

Я несколько запутался, как работают мягкие ссылки в Unix. Смотрите пример.

% cd /usr/local/
% ls -la
total 6
drwxr-xr-x   2 root     root         512 Jan 19 15:03 .
drwxr-xr-x  41 root     sys         1024 Jan 20 16:24 ..
lrwxrwxrwx   1 root     root          38 Jan 19 15:03 java -> /otherDir/java/jdk1.6.0_17 **<- this is a soft link**

% cd java **<- move to the softlink**

% pwd
/usr/local/java **<- the current location, say LOCATION_A**

% cd /otherDir/java/jdk1.6.0_17/ **<-move to the location of the softlink**

% pwd
/otherDir/java/jdk1.6.0_17 **<- the new current location, say LOCATION_B**

Разве не проблематично, что, хотя LOCATION_A и есть LOCATION_B, у них разные пути?

Есть ли команда (кроме pwd), которая даст реальное местоположение файла (а не только то, как пользователь туда пойдет).

Мне кажется, что pwd - это просто сумма компакт-диска пользователя. НЕ их текущее местоположение.

6 ответов

Решение

Это ведет себя так с целью. Если вы перейдете на /a/b/c/d а затем перейдите к .. тогда вы реально ожидаете быть в /a/b/c, Если c оказывается символическая ссылка (или символическая ссылка в терминах Unix - но не мягкая ссылка), которая приводит вас к /f/g/hс поведением, которое вы хотели бы иметь, вы бы в конечном итоге /f/g и тогда вы (или любая другая программа) не поймете, как она туда попала.

Пытаться pwd -P, Это не "кроме pwd", но это помогает, по крайней мере, на моем bash 4.0.35 на Fedora 12. YMMV.

Обновление: даже работает с sh, так что, кажется, портативный.

Обычно, pwd должен вернуться /usr/local/java в последней строке, если я понимаю ваш пример. Но в некоторых оболочках есть pwd команда, которая пытается быть более "умной", обрабатывая символические ссылки в текущем рабочем каталоге.

Пытаться /bin/pwd Вы получаете другие результаты?

Вы можете использовать readlink для текущего рабочего каталога, чтобы получить истинное имя каталога:

readlink `pwd`

Невозможно абсолютно точно найти свой путь при любых обстоятельствах. Это немного странно, но вариация этого (плюс chroot и setuid) иногда используется для блокировки процесса.

$ mkdir -p /tmp/a/b
$ cd /tmp/a/b
$ rmdir /tmp/a/b
$ chmod 0 /tmp/a
$ rmdir /tmp/a
$ ls ..
ls: не могу открыть каталог..: Отказано в доступе
$ ls -al
всего 0
$ pwd -P
pwd: ошибка при получении текущего каталога: getcwd: невозможно получить доступ к родительским каталогам: нет такого файла или каталога

RealPath делает то, что вы хотите.

Другие вопросы по тегам