Как сделать, чтобы realpath никогда не разрешал символические ссылки?

Что бы это ни стоило... следуя предложениям в комментариях выше, я переписал код, который дает мне файл, на который указывает ссылка, даже если это другая ссылка, плюс несколько строк для проверки:

#!/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?

1
02.04.2020, 09:52
1 ответ

Текущий рабочий каталог (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
}
1
28.04.2021, 23:19

Теги

Похожие вопросы