如何在通过符号链接调用脚本时获取脚本文件路径

11

当我需要在脚本内部获取脚本文件的路径时,我会使用类似这样的代码:

`dirname $0`

这个代码能够正常工作,直到我通过符号链接调用脚本。在这种情况下,上面的代码会打印出链接的位置而不是原始文件。

有没有一种方法可以获取原始脚本文件的路径,而不是链接的路径?

谢谢, Mike


好的。我在这里找到了答案: https://dev59.com/5nVD5IYBdhLWcg3wWaNh - Ma99uS
5个回答

17
if [ -L $0 ] ; then
    DIR=$(dirname $(readlink -f $0)) ;
else
    DIR=$(dirname $0) ;
fi ;

如果readlink不可用,答案在这里: https://dev59.com/5nVD5IYBdhLWcg3wWaNh - Ma99uS
好奇为什么需要在$0是符号链接或不是符号链接时运行不同的命令?https://unix.stackexchange.com/questions/432475/apply-readlink-to-a-non-symlink-file - Tim
为什么不管$0是否包含符号链接,都不直接使用$(dirname $(readlink -f $0))呢? - Tim

17

确实需要阅读以下的BashFAQ文章:

事实上,$0的替代方法是不可靠的,并且只要应用程序使用的零th参数不是应用程序的路径,它们就会失败。例如,login(1)将在$0中的应用程序名称前面加上一个-,导致错误,并且每当调用在PATH中的应用程序时,$0将不包含应用程序的路径,而只包含文件名,这意味着您无法从中提取任何位置信息。有很多其他可能会导致此操作失败的方式。

底线:不要依赖这种替代方法,事实上你无法弄清楚你的脚本在哪里,所以使用配置选项来设置你的配置文件所在的目录或者你需要脚本路径的任何东西。


感谢您提供详细的答案。我会查看常见问题解答。 - Ma99uS

6

可以使用readlink来实现:

readlink -f "$0"

1
我建议使用这个:

dirname $(realpath $0)

例子:
skaerst@test01-centos7:~/Documents> ../test/path.sh 
dirname realpath: /home/skaerst/test

skaerst@test01-centos7:~/Documents> cat ../test/path.sh
#!/bin/bash

echo "dirname realpath: $(dirname $(realpath $0))"

即使使用符号链接,也可以正常工作,因为realpath默认使用-P:

skaerst@test01-centos7:~/Documents> ln -s ../test/path.sh p
skaerst@test01-centos7:~/Documents> ./p
dirname realpath: /home/skaerst/test

realpath在coreutils >8.5中可用,我猜

skaerst@test01-centos7:~/Documents> rpm -qf $(which realpath) $(which dirname)
coreutils-8.22-15.el7_2.1.x86_64
coreutils-8.22-15.el7_2.1.x86_64
Regards
Stefan

1
Dir=$(dirname $(readlink -f "$0"))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接