从脚本中查找绝对路径

从脚本中查找绝对路径

在脚本中,我获取了$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\)

相关内容