这段代码来自堆栈溢出是获取脚本内部脚本父目录的路径名,即使脚本是通过符号链接运行的:
if [ -L $0 ] ; then
DIR=$(dirname $(readlink -f $0)) ;
else
DIR=$(dirname $0) ;
fi ;
上面的代码是否等价于
DIR=$(dirname $(readlink -f $0)) ;
即是否真的需要测试是否$0
是符号链接,如果是,如果不是则运行不同的命令?
为什么不直接使用$(dirname $(readlink -f $0))
无论是否$0
包含符号链接?
具体来说,如果$0
包含符号链接,那么使用$(dirname $(readlink -f $0))
.
如果$0
不是符号链接,那么对我来说使用以下命令似乎很完美$(dirname $(readlink -f $0))
:
$(readlink -f $0)
返回 的绝对路径$0
,并$(dirname $(readlink -f $0))
返回 的父目录的绝对路径$0
$(dirname $0)
返回 的父级路径$0
,返回的是绝对路径还是相对路径,具体取决于 if$0
是绝对路径还是相对路径。我认为 的值
DIR
是绝对路径还是相对路径在原始代码中并不重要,因为无论哪种情况, 的值DIR
都是指 的父目录$0
。那么$(dirname $(readlink -f $0))
和$(dirname $0)
在原始代码中是等价的吗?
谢谢。
答案1
您应该使用"$0"
和dirname "$()"
。
这些命令并不等效,因为 shell 测试仅影响路径中的最后一个组件,但readlink -f
会影响所有路径级别。
mkdir physdir
touch physdir/file
ln -s physdir symlink
test -L symlink/file ; echo $?
1
test -L symlink ; echo $?
0
dirname symlink/file
symlink
dirname "$(readlink -f symlink/file)"
/crypto/home/hl/tmp/stackexchange/readlink/physdir
因此,对于相对路径,输出完全不同,但即使对于绝对路径,其中的符号链接目录也不同。
答案2
我认为是否存在差异取决于您所使用的 unix 的确切风格。例如,在 OSX 上,readlink 没有-f
标志并声明:
如果给定的参数不是符号链接,readlink 将不打印任何内容并退出并返回错误
如果您知道您的操作系统支持该-f
标志,那么应该没有任何区别。
事实上-mflag 可能是使用最灵活的一种。