在脚本中,我获取了$0
它的可能相对路径。为了将其转换为绝对值,我找到了这个我不明白的解决方案:
abspath=$(cd ${0%/*} && echo $PWD/${0##*/})
${0%/*}
我的问题是and内部的魔力${0##*/}
。看起来前者提取目录名,后者提取文件名,我只是不明白如何。
答案1
肖恩有一个最简单的解决方案:readlink -f $0
。如果你想绝对确定处理奇怪的文件名,你可以使用这个:
absolute_path_x="$(readlink -fn -- "$0"; echo x)"
absolute_path="${absolute_path_x%x}"
答案2
定义:
${string%substring}
$substring
从 的末尾 删除 的最短匹配项$string
。
${string##substring}
$substring
从 的开头删除 的最长匹配项$string
。
你的例子:
abspath=$(cd ${0%/*} && echo $PWD/${0##*/})
${0%/*}
删除最后一个斜杠之后的所有内容,为您提供脚本的目录名称(可能是相对路径)。
${0##*/}
删除最后一个斜杠之前的所有内容,只给出脚本的名称。
因此,此命令更改为脚本的目录,并将当前工作目录(由 给出$PWD
)和脚本名称连接起来,为您提供绝对路径。
要查看发生了什么,请尝试:
echo ${0%/*}
echo ${0##*/}
答案3
这是完成这项工作的一种更安全、更易读的方法:
abspath=$(unset CDPATH && cd "$(dirname "$0")" && echo $PWD/$(basename "$0"))
笔记:
- 如果
$0
是一个没有前面路径的裸文件名,则原始脚本将失败,但此处给出的脚本将起作用。 (这不是问题,$0
但在其他应用程序中可能会出现问题。) - 如果文件的路径实际上不存在,则任何一种方法都会失败。 (对于 来说不是问题
$0
,但在其他应用程序中可能会出现问题。) unset
如果您的用户可能已CDPATH
设置,则这是必需的。readlink -f
与或不同realpath
,这适用于非 Linux 版本的 Unix(例如 Mac OS X)。
答案4
介绍 bash 内置命令 pwd。也可以在 GNU coreutils 包中找到。
$ sh ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
$0: ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
cheeky binary from /home/jaroslav/tmp (/home/jaroslav/tmp)
$ cat /home/jaroslav/tmp/somewhere.sh
abs=$( cd `dirname "$0"` ; pwd -P)
absBin=$( cd `dirname "$0"` ; /bin/pwd -P)
echo \$0: $0
echo cheeky binary from $abs \($absBin\)