我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
没有<unk>(除了<unk>)和可以处理“陌生人”名称的形式,如那些有新闻,因为有些人会声称:
IFS= read -rd '' DIR < <([[ $BASH_SOURCE != */* ]] || cd "${BASH_SOURCE%/*}/" >&- && echo -n "$PWD")
其他回答
下面将返回剧本的当前目录
工作,如果它是源,或者不源工作,如果运行在当前的目录,或某些其他目录.工作,如果相对目录被使用.工作与 bash,不确定其他<unk>。
/tmp/a/b/c $ . ./test.sh
/tmp/a/b/c
/tmp/a/b/c $ . /tmp/a/b/c/test.sh
/tmp/a/b/c
/tmp/a/b/c $ ./test.sh
/tmp/a/b/c
/tmp/a/b/c $ /tmp/a/b/c/test.sh
/tmp/a/b/c
/tmp/a/b/c $ cd
~ $ . /tmp/a/b/c/test.sh
/tmp/a/b/c
~ $ . ../../tmp/a/b/c/test.sh
/tmp/a/b/c
~ $ /tmp/a/b/c/test.sh
/tmp/a/b/c
~ $ ../../tmp/a/b/c/test.sh
/tmp/a/b/c
测试.sh
#!/usr/bin/env bash
# snagged from: https://stackoverflow.com/a/51264222/26510
function toAbsPath {
local target
target="$1"
if [ "$target" == "." ]; then
echo "$(pwd)"
elif [ "$target" == ".." ]; then
echo "$(dirname "$(pwd)")"
else
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
fi
}
function getScriptDir(){
local SOURCED
local RESULT
(return 0 2>/dev/null) && SOURCED=1 || SOURCED=0
if [ "$SOURCED" == "1" ]
then
RESULT=$(dirname "$1")
else
RESULT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
fi
toAbsPath "$RESULT"
}
SCRIPT_DIR=$(getScriptDir "$0")
echo "$SCRIPT_DIR"
我用三种不同的处决尝试了追踪。
echo $(实际上是 $_)
. application # /correct/path/to/dir or /path/to/temporary_dir
bash application # /path/to/bash
/PATH/TO/application # /correct/path/to/dir
echo $(相当于 $(相当于 $0))
. application # failed with `realpath: missing operand`
bash application # /correct/path/to/dir
/PATH/TO/application # /correct/path/to/dir
echo $(相当于 $BASH_SOURCE)
$BASH_SOURCE 基本上与 ${BASH_SOURCE[0]} 相同。
. application # /correct/path/to/dir
bash application # /correct/path/to/dir
/PATH/TO/application # /correct/path/to/dir
只有$(实际上是$BASH_SOURCE)似乎是可靠的。
简短答案:
"`dirname -- "$0";`"
或(最好是):
"$( dirname -- "$0"; )"
尝试一下这样的东西:
function get_realpath() {
if [[ -f "$1" ]]
then
# The file *must* exist
if cd "$(echo "${1%/*}")" &>/dev/null
then
# The file *may* not be local.
# The exception is ./file.ext
# tTry 'cd .; cd -;' *works!*
local tmppwd="$PWD"
cd - &>/dev/null
else
# file *must* be local
local tmppwd="$PWD"
fi
else
# The file *cannot* exist
return 1 # Failure
fi
# Reassemble realpath
echo "$tmppwd"/"${1##*/}"
return 0 # Success
}
function get_dirname(){
local realpath="$(get_realpath "$1")"
if (( $? )) # True when non-zero.
then
return $? # Failure
fi
echo "${realpath%/*}"
return 0 # Success
}
# Then from the top level:
get_dirname './script.sh'
# Or within a script:
get_dirname "$0"
# Can even test the outcome!
if (( $? )) # True when non-zero.
then
exit 1 # Failure
fi
這些功能和相關工具是我們的產品的一部分,已為社區提供免費,可以在GitHub找到作為 realpath-lib. 它是簡單的,清潔和良好的文档(很棒的學習),純粹的Bash,並沒有依賴。
source '/path/to/realpath-lib'
get_dirname "$0"
if (( $? )) # True when non-zero.
then
exit 1 # Failure
fi
基于这个答案,我建议一个明确的版本,获得SCRIPT_HOME作为包含任何目前运行的Bash脚本的文件夹:
s=${BASH_SOURCE[0]} ; s=`dirname $s` ; SCRIPT_HOME=`cd $s ; pwd`
echo $SCRIPT_HOME