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

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

$ ./application

当前回答

查看下面的测试与奇怪的目录名称。

要将工作目录更改为Bash脚本的位置,您应该尝试这个简单的,测试和验证的Shellcheck解决方案:

#!/bin/bash --
cd "$(dirname "${0}")"/. || exit 2

测试:

$ ls 
application
$ mkdir "$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47testdir" "")"
$ mv application *testdir
$ ln -s *testdir "$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47symlink" "")"
$ ls -lb
total 4
lrwxrwxrwx 1 jay stacko   46 Mar 30 20:44 \001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ !"#$%&'symlink -> \001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ !"#$%&'testdir
drwxr-xr-x 2 jay stacko 4096 Mar 30 20:44 \001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ !"#$%&'testdir
$ *testdir/application && printf "SUCCESS\n" ""
SUCCESS
$ *symlink/application && printf "SUCCESS\n" ""
SUCCESS

其他回答

$0 不是一个可靠的方式来获得当前的脚本路径. 例如,这是我的.xprofile:

#!/bin/bash
echo "$0 $1 $2"
echo "${BASH_SOURCE[0]}"
# $dir/my_script.sh &

cd /tmp && ~/.xprofile && 来源 ~/.xprofile

/home/puchuu/.xprofile
/home/puchuu/.xprofile
-bash
/home/puchuu/.xprofile

因此,请使用 BASH_SURCE 代替。

$(dirname "$(readlink -f "$BASH_SOURCE")")

尝试一下这样的东西:

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
function getScriptAbsoluteDir { # fold>>
    # @description used to get the script path
    # @param $1 the script $0 parameter
    local script_invoke_path="$1"
    local cwd=`pwd`

    # absolute path ? if so, the first character is a /
    if test "x${script_invoke_path:0:1}" = 'x/'
    then
        RESULT=`dirname "$script_invoke_path"`
    else
        RESULT=`dirname "$cwd/$script_invoke_path"`
    fi
} # <<fold
#!/bin/sh
PRG="$0"

# need this for relative symlinks
while [ -h "$PRG" ] ; do
   PRG=`readlink "$PRG"`
done

scriptdir=`dirname "$PRG"`