我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
這是Linux的特點,但你可以使用:
SELF=$(readlink /proc/$$/fd/255)
其他回答
我不认为这是像其他人这样容易的。 pwd 不工作,因为当前的目录不一定是与脚本的目录。 $0 不总是有信息。
./script
/usr/bin/script
script
在第一和第三方式 $0 没有完整的路径信息. 在第二和第三, pwd 不工作. 唯一的方式来获得目录的第三方式将是通过路径运行并找到文件与正确的匹配。
做你正在要求的一种方式,就是在 /usr/share 目录中的数据硬编码,并将其引用到其完整的路径。
下面是简单而正确的方式:
actual_path=$(readlink -f "${BASH_SOURCE[0]}")
script_dir=$(dirname "$actual_path")
解释:
${BASH_SOURCE[0]} - 完整的路径到脚本. 这个值将是正确的,即使脚本是源,例如源 <(echo 'echo $0') 打印 bash,同时取代它为 ${BASH_SOURCE[0]} 将打印整个路径的脚本。
下面存储了脚本的目录路径在Dir变量中。
(它也试图支持在Windows中的Cygwin下运行。
最后,它运行我的样本应用程序可执行,所有通过到这个脚本的论点使用“$@”:
#!/usr/bin/env sh
dir=$(cd "${0%[/\\]*}" > /dev/null && pwd)
if [ -d /proc/cygdrive ]; then
case "$(uname -s)" in
CYGWIN*|MINGW32*|MSYS*|MINGW*)
# We are under Windows, so translate path to Windows format.
dir=$(cygpath -m "$dir");
;;
esac
fi
# Runs the executable which is beside this script
"${dir}/my-sample-app" "$@"
选择的答案非常好,我把我的解决方案发送给任何人寻找更短的替代方案,这些解决方案仍然涉及来源、执行、完整路径、相对路径和同步链接,最后,这将在 macOS 上工作,因为不能假设GNU的核心路径的阅读链接版本可用。
GOTCHA是它不使用Bash,但它很容易在Bash脚本中使用,虽然OP没有在解决方案的语言上设置任何限制,但它可能是最好的,大多数人已经留在Bash世界中。
PHP 可在 macOS 默认情况下,并安装在其他平台上,但不一定是默认情况下. 我意识到这是一个缺点,但我会留下这个在这里,任何人来自搜索引擎,无论如何。
export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"
大多数答案都不会处理通过相对路径连接的文件,不是单线或不处理BSD(Mac)。
HERE=$(cd "$(dirname "$BASH_SOURCE")"; cd -P "$(dirname "$(readlink "$BASH_SOURCE" || echo .)")"; pwd)
首先, cd 到 bash 的概念的脚本的目录. 然后 readlink 文件,以查看它是否是一个 symlink (相对或其他), 如果是这样, cd 到该目录. 否则, cd 到当前目录(需要保持事物一个单线)。 然后 echo 当前目录通过 pwd。
你可以添加 - 到CD和阅读链接的论点,以避免名为选项的目录问题,但我不在乎大多数目的。
你可以看到完整的解释与图像在这里:
https://www.binaryphile.com/bash/2020/01/12/determining-the-location-of-your-script-in-bash.html