我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
我会用这样的东西:
# Retrieve the full pathname of the called script
scriptPath=$(which $0)
# Check whether the path is a link or not
if [ -L $scriptPath ]; then
# It is a link then retrieve the target path and get the directory name
sourceDir=$(dirname $(readlink -f $scriptPath))
else
# Otherwise just get the directory name of the script path
sourceDir=$(dirname $scriptPath)
fi
其他回答
pushd . > '/dev/null';
SCRIPT_PATH="${BASH_SOURCE[0]:-$0}";
while [ -h "$SCRIPT_PATH" ];
do
cd "$( dirname -- "$SCRIPT_PATH"; )";
SCRIPT_PATH="$( readlink -f -- "$SCRIPT_PATH"; )";
done
cd "$( dirname -- "$SCRIPT_PATH"; )" > '/dev/null';
SCRIPT_PATH="$( pwd; )";
popd > '/dev/null';
它适用于所有版本,包括
当通过多个深度软链接呼叫时,当文件时,当脚本被命令“源”称为. (dot) 操作员时,当 arg $0 从呼叫器修改时,“./script” “/full/path/to/script” “/some/path/../../other/path/script” “./some/folder/script”
否则,如果Bash脚本本身是一个相对的Symlink,你想跟随它并返回链接到脚本的完整路径:
pushd . > '/dev/null';
SCRIPT_PATH="${BASH_SOURCE[0]:-$0}";
while [ -h "$SCRIPT_PATH" ];
do
cd "$( dirname -- "$SCRIPT_PATH"; )";
SCRIPT_PATH="$( readlink -f -- "$SCRIPT_PATH"; )";
done
cd "$( dirname -- "$SCRIPT_PATH"; )" > '/dev/null';
SCRIPT_PATH="$( pwd; )";
popd > '/dev/null';
SCRIPT_PATH 以完整的路径提供,无论它是如何称呼的。
只需确保您在脚本开始时找到此处。
关键部分是,我正在减少问题的范围:我禁止通过路径间接执行脚本(如 /bin/sh [脚本路径与路径组件有关])。
这可以被检测到,因为0美元将是一个相对的路径,不解决与当前文件夹有关的任何文件。我相信使用#!机制的直接执行总是导致绝对0美元,包括当脚本在路径上找到时。
我也要求在象征性链接链接链接的任何字符和字符只包含一个合理的字符子,特别是不是 \n, >, * 或?. 这对于字符逻辑来说是必要的。
#!/bin/sh
(
path="${0}"
while test -n "${path}"; do
# Make sure we have at least one slash and no leading dash.
expr "${path}" : / > /dev/null || path="./${path}"
# Filter out bad characters in the path name.
expr "${path}" : ".*[*?<>\\]" > /dev/null && exit 1
# Catch embedded new-lines and non-existing (or path-relative) files.
# $0 should always be absolute when scripts are invoked through "#!".
test "`ls -l -d "${path}" 2> /dev/null | wc -l`" -eq 1 || exit 1
# Change to the folder containing the file to resolve relative links.
folder=`expr "${path}" : "\(.*/\)[^/][^/]*/*$"` || exit 1
path=`expr "x\`ls -l -d "${path}"\`" : "[^>]* -> \(.*\)"`
cd "${folder}"
# If the last path was not a link then we are in the target folder.
test -n "${path}" || pwd
done
)
我想确保剧本在其目录中运行。
cd $(dirname $(which $0) )
接下来,如果你真的想知道你在哪里运行,然后运行下面的命令。
DIR=$(/usr/bin/pwd)
请尝试以下交互式解决方案:
CWD="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
如 realpath 或 readlink 等命令可能无法使用(取决于操作系统)。
注意: 在 Bash 中,建议使用 ${BASH_SOURCE[0]} 而不是 $0,否则路径在提取文件时可能会破裂(源/)。
否则,您可以在Bash中尝试下列功能:
realpath () {
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
这个函数需要一个论点. 如果论点已经有绝对的路径,打印它如有,否则打印 $PWD 变量 + 文件名论点(没有./ 预定)。
相关:
如何将当前的工作目录设置为Bash中的脚本目录?Bash脚本绝对路径与OS X可靠路径为Bash脚本获得完整路径
好吧,如果在路上,字母和字母只是不会切断它,走路是艰难的(如果父母没有出口PATH?!)。
然而,盾牌必须对其脚本有一个开放的手稿,而在Bash手稿是#255。
SELF=`readlink /proc/$$/fd/255`
为我工作。