我把我的 bash 脚本安装/usr/bin/app.sh
到/usr/bin/lib.sh
app.sh
包括
source "/usr/bin/lib.sh"
并lib.sh
包括
if [ "/usr/bin/app.sh" == "$0"] ...
app.sh
当我从 shell运行时,此测试失败,因为$0
实际上是/bin/app.sh
。在文件系统上,/bin
是指向/usr/bin
lib.sh
确定它是否被包含在内app.sh
(而不是other-app.sh
),从而不会被环境欺骗的最佳方法是什么?我原本以为没有符号链接的绝对路径可以完成这项工作,但显然不是。
答案1
要检查两个文件是否相同,需要检查索引(inode)号,其显示内容为:
stat -L -c %i FilePath
因此你的支票现在变成:
if [ $(stat -L -c %i "/usr/bin/app.sh") == $(stat -L -c %i "$0") ] ...
无论目录路径中有什么链接,甚至是文件本身的符号或硬链接,这都可以起作用。
严格地说(感谢 @ilkkachu 指出这一点),两个同名的不同文件在两个不同的文件系统上具有相同的 inode 的可能性非常小。为避免这种情况,请在比较中包含设备编号:
if [ $(stat -L -c %d:%i "/usr/bin/app.sh") == $(stat -L -c %d:%i "$0") ] ...
答案2
readlink -f /path/to/whatever
将告诉您规范路径(将/usr/bin/app.sh
在您的示例中)。
从手册页:
通过递归跟踪给定名称的每个组件中的每个符号链接来规范化;除最后一个组件外,其他所有组件都必须存在