Что бы это ни стоило... следуя предложениям в комментариях выше, я переписал код, который дает мне файл, на который указывает ссылка, даже если это другая ссылка, плюс несколько строк для проверки:
#!/bin/bash
function nextlinked ()
{
if [ -h "$1" ]; then # we have a link
linked="$(readlink "$1")"
[ "${linked:0:1}" == / ] && echo "$linked" || echo "${1%/*}"/"$linked"
fi
}
header=""
add=" "
count=0
find / -print0 | while read -rd '' FILENAME ; do
(( count++ ))
if [ -h "$FILENAME" ] ; then # is this a link?
filename="$FILENAME"
printf "%6d " $count ; ls -ld "$filename" 2>&1
filename="$(nextlinked "$filename" )"
while [ "$filename" ] ; do
header=$header$add
printf "%6d %s" $count "$header" ; ls -ld "$filename" 2>&1
filename="$(nextlinked "$filename")"
done
header=""
fi
done
Вопрос остается в силе. :Существует ли в Linux команда, выполняющая работу функции nextlinked?
Текущий рабочий каталог (CWD )процесса наследуется на уровне ОС от предыдущего процесса или может быть изменен для текущего процесса с помощью chdir(2)
. ОС (здесь я имею в виду «ядро» ), конечно, всегда будет разрешать любую символическую ссылку, чтобы определить конечный результат, который должен быть каталогом, а не символической ссылкой (на каталог ). Например, предыдущий системный вызов(chdir(2)
)может возвращать ошибку ELOOP
, когда необходимо разрешить слишком много символических ссылок. Таким образом, с точки зрения ОС не может быть CWD, не являющегося каталогом для какого-либо процесса :, ОС всегда будет разрешать его по реальному пути без каких-либо символических ссылок.
После того, как оболочка выполнила cd /tmp/test/bar
, путь CWD был преобразован операционной системой в /tmp/test/foo
. Например, в системе Linux ls -l /proc/$$/cwd
покажет ссылку на разрешенный путь, видимый ядру :/tmp/test/foo
.
Тот факт, что оболочка по-прежнему отображает bar
в своей подсказке, объясняется тем, что она помнит ранее выполненную команду cd . Поведение может зависеть от типа оболочки. Я возьму bash здесь. Таким образом, встроенная -в pwd
(, но не внешняя /bin/pwd
команда ), переменная $PWD
и их использование в $PS1
будут «лгать» пользователю о текущем каталоге.
Любой процесс, например realpath
или /bin/pwd
, запущенный из оболочки, конечно же, наследует фактический CWD, то есть /tmp/test/foo
. Так что это не ошибка в realpath
, у него никогда не будет конкретной информации о bar
.
Один из возможных неудобных способов, предложенный Кусаланандой, заключается в повторном использовании переменной $PWD
и добавлении ее к аргументу realpath
только в том случае, если ее аргумент уже не является абсолютным.
Вот пример. Я не уверен, что нет способов злоупотребить этим. Например, хотя приведенная ниже функция справилась бы, сама переменная $PWD
плохо работает в bash 4.4.12 (Debian 9 ), но отлично работает в bash 5.0.3 (Debian 10 )если в пути есть символ перевода строки.Когда где-то есть перевод строки, чтобы быть полезным, параметр -z
также должен быть добавлен к realpath
, но я не собираюсь заново реализовывать весь синтаксический анализ параметров в этом простом примере.
myrealpathnofollowsym () {
for p in "$@"; do
if ! printf '%s' "$p" | grep -q -- '^/'; then
realpath -se "$PWD/$p"
else
realpath -se "$p"
fi
done
}