我如何找到一个Bash脚本位于该脚本内部的目录的路径?

我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:

$ ./application

当前回答

以下是一個符合 POSIX 的單線:

SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"`

# test
echo $SCRIPT_PATH

其他回答

这种方法的一个好处是,它不涉及Bash本身以外的任何东西,也不会破坏任何底层。

首先,使用模式替代替代不以 / (即相对路径) 以 $ PWD/. 因为我们使用替代替代相匹配的第一个字符为 $ 0,我们也必须添加它回来(${0:0:1} 在替代中)。

现在我们有一个完整的路径到脚本;我们可以通过删除最后的 / 和随后的任何东西(即脚本名称)来获得目录。

#!/bin/bash

BIN=${0/#[!\/]/"$PWD/${0:0:1}"}
DIR=${BIN%/*}

cd "$DIR"

如果您的脚本可以源于而不是执行,您可以将 $0 取代 ${BASH_SOURCE[0]},例如:

BIN=${BASH_SOURCE[0]/#[!\/]/"$PWD/${BASH_SOURCE[0]:0:1}"}

这将为可执行的脚本工作,它更长,但更多。

cur_dir=`old=\`pwd\`; cd \`dirname $0\`; echo \`pwd\`; cd $old;`

这是我唯一能以可靠的方式说的话:

SCRIPT_DIR=$(dirname $(cd "$(dirname "$BASH_SOURCE")"; pwd))
SCRIPT_DIR=$( cd ${0%/*} && pwd -P )

尝试一下这样的东西:

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