Ошибка команды readlink после выполнения команды pushd в скриптах bash

Я столкнулся с одной сложной проблемой, которую я пытался объяснить на простом примере, как показано ниже

В моей системе у меня есть

ubuntu@ubuntu:~/temp$ pwd
/home/ubuntu/temp
ubuntu@ubuntu:~/temp$ ls
temp1  test.sh
ubuntu@ubuntu:~/temp$ 

В темп.ш у меня есть

#!/bin/bash

echo "Arg 0 = $0"
echo "Arg 1 = $1"
echo "Arg 0 Full Path $(readlink -f $0)"
echo "Arg 1 Full Path $(readlink -f $1)"
pushd /var/log
echo "Arg 0 = $0"
echo "Arg 1 = $1"
echo "Arg 0 Full Path $(readlink -f $0)"
echo "Arg 1 Full Path $(readlink -f $1)"

Теперь я бегу по пути ниже

ubuntu@ubuntu:~/temp$ ./test.sh temp1
Arg 0 = ./test.sh
Arg 1 = temp1
Arg 0 Full Path /home/ubuntu/temp/test.sh
Arg 1 Full Path /home/ubuntu/temp/temp1
/var/log ~/temp
Arg 0 = ./test.sh
Arg 1 = temp1
Arg 0 Full Path /var/log/test.sh
Arg 1 Full Path /var/log/temp1

Здесь вы можете увидеть readlink показывает неверный путь к файлам Arg0 и Arg1 после выдачи pushd команда. Если я удаляю команду popd, то она печатается нормально.

Так почему здесь readlink шалить?

2 ответа

Решение

Учитывая относительные пути, readlink будет интерпретировать их относительно рабочего каталога процесса и выводить абсолютные пути (разрешая символические ссылки между ними).

Ключевым моментом здесь является рабочий каталог процесса (он же текущий каталог).

Так readlink ./path/to/file будет выводить /tmp/path/to/file если /tmp является текущим каталогом (без символических ссылок).

Другая команда, которую вы используете, pushd изменит рабочий процесс каталога.

Так в последовательности

readlink ./path/to/file
pushd /some/other/place
readlink ./path/to/file

и то и другое readlink скорее всего разрешит два разных абсолютных пути.

Здесь нет плохого поведения. Все по дизайну.

readlink здесь ведет себя правильно, здесь нужно понимать только pushd, pushd команда для изменения текущего стека каталогов Давайте разберемся с картинкой снизу.

введите описание изображения здесь

Первоначально test.sh был какой-то полный путь, после запуска pushd еще один каталог т.е. (/var/log) вставляется в стек каталогов. Самый левый каталог (или самый верхний каталог) стека становится текущим каталогом. И если вы бежите popd, это означает, что стек становится пустым сверху. Как только ты побежишь readlink -f test.sh снова после popd, у вас будет начальный каталог. В вашем случае это будет /home/ubuntu/temp/test.sh

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