Ошибка команды 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