在 bash 个脚本中发出 pushd 命令后 readlink 命令行为异常
readlink command misbehave after issueing pushd command in bash scripts
我遇到了一个复杂的问题,我试着用下面的简单例子来解释它
在我的系统中我有
ubuntu@ubuntu:~/temp$ pwd
/home/ubuntu/temp
ubuntu@ubuntu:~/temp$ ls
temp1 test.sh
ubuntu@ubuntu:~/temp$
在temp.sh我有
#!/bin/bash
echo "Arg 0 = [=12=]"
echo "Arg 1 = "
echo "Arg 0 Full Path $(readlink -f [=12=])"
echo "Arg 1 Full Path $(readlink -f )"
pushd /var/log
echo "Arg 0 = [=12=]"
echo "Arg 1 = "
echo "Arg 0 Full Path $(readlink -f [=12=])"
echo "Arg 1 Full Path $(readlink -f )"
现在我运行在下面的路
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
在发出 pushd
命令后显示了错误的 Arg0 和 Arg1 文件路径。
如果我删除 popd 命令,那么它打印正常。
那么为什么这里 readlink
行为不端?
readlink
在这里的行为是正确的,这里唯一需要理解的是 pushd
的行为。 pushd
是改变当前目录堆栈的命令。看下图就明白了。
最初 test.sh
有一些完整路径,在 运行 宁 pushd
一个目录后,即 (/var/log
) 被插入到目录堆栈中。
堆栈的最左边目录(或最顶层目录)成为当前目录。
如果你 运行 popd
,这意味着堆栈从顶部开始变空。只要你在 popd
之后再次 运行 readlink -f test.sh
,你就会有初始目录。在你的情况下它将是 /home/ubuntu/temp/test.sh
给定相对路径,readlink
将相对于进程工作目录解释它们,并输出绝对路径(解析中间的符号链接)。
这里的关键点是进程工作目录(又名当前目录)。
所以如果/tmp
是当前目录(假设没有符号链接),readlink ./path/to/file
将输出/tmp/path/to/file
。
您正在使用的另一个命令,pushd
将更改进程工作目录。
所以顺序
readlink ./path/to/file
pushd /some/other/place
readlink ./path/to/file
两者 readlink
都可能解析为两个不同的绝对路径。
这里没有不当行为。完全由设计决定。
我遇到了一个复杂的问题,我试着用下面的简单例子来解释它
在我的系统中我有
ubuntu@ubuntu:~/temp$ pwd
/home/ubuntu/temp
ubuntu@ubuntu:~/temp$ ls
temp1 test.sh
ubuntu@ubuntu:~/temp$
在temp.sh我有
#!/bin/bash
echo "Arg 0 = [=12=]"
echo "Arg 1 = "
echo "Arg 0 Full Path $(readlink -f [=12=])"
echo "Arg 1 Full Path $(readlink -f )"
pushd /var/log
echo "Arg 0 = [=12=]"
echo "Arg 1 = "
echo "Arg 0 Full Path $(readlink -f [=12=])"
echo "Arg 1 Full Path $(readlink -f )"
现在我运行在下面的路
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
在发出 pushd
命令后显示了错误的 Arg0 和 Arg1 文件路径。
如果我删除 popd 命令,那么它打印正常。
那么为什么这里 readlink
行为不端?
readlink
在这里的行为是正确的,这里唯一需要理解的是 pushd
的行为。 pushd
是改变当前目录堆栈的命令。看下图就明白了。
最初 test.sh
有一些完整路径,在 运行 宁 pushd
一个目录后,即 (/var/log
) 被插入到目录堆栈中。
堆栈的最左边目录(或最顶层目录)成为当前目录。
如果你 运行 popd
,这意味着堆栈从顶部开始变空。只要你在 popd
之后再次 运行 readlink -f test.sh
,你就会有初始目录。在你的情况下它将是 /home/ubuntu/temp/test.sh
给定相对路径,readlink
将相对于进程工作目录解释它们,并输出绝对路径(解析中间的符号链接)。
这里的关键点是进程工作目录(又名当前目录)。
所以如果/tmp
是当前目录(假设没有符号链接),readlink ./path/to/file
将输出/tmp/path/to/file
。
您正在使用的另一个命令,pushd
将更改进程工作目录。
所以顺序
readlink ./path/to/file
pushd /some/other/place
readlink ./path/to/file
两者 readlink
都可能解析为两个不同的绝对路径。
这里没有不当行为。完全由设计决定。