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

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

$ ./application

当前回答

这对我来说工作了,当这里的其他答案没有:

thisScriptPath=`realpath $0`
thisDirPath=`dirname $thisScriptPath`
echo $thisDirPath

其他回答

这是令人不安的,我发现的唯一一个线路,它在Linux和macOS工作,当执行的脚本是一个同步链接:

SCRIPT_DIR=$(python -c "import os; print(os.path.dirname(os.path.realpath('${BASH_SOURCE[0]}')))")

或,类似,使用Python3 pathlib模块:

SCRIPT_DIR=$(python3 -c "from pathlib import Path; print(Path('${BASH_SOURCE[0]}').resolve().parent)")

在Linux和macOS上进行测试,并与其他解决方案进行比较: https://gist.github.com/ptc-mrucci/61772387878ed53a6c717d51a21d9371

在我看来,最合适的解决方案是:

"$( cd "$( echo "${BASH_SOURCE[0]%/*}" )"; pwd )"

使用 dirname、 readlink 和 basename 最终会导致兼容性问题,所以如果可能的话最好避免。

您可以使用 $BASH_SOURCE:

#!/usr/bin/env bash

scriptdir="$( dirname -- "$BASH_SOURCE"; )";

请注意,您需要使用 #!/bin/bash 而不是 #!/bin/sh 因为它是一个 Bash 扩展。

#!/bin/sh
PRG="$0"

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

scriptdir=`dirname "$PRG"`

我已经比较了许多答案,并出现了一些更紧凑的解决方案. 这些似乎处理所有疯狂的边缘案例,从你最喜欢的组合:

绝对路径或相对路径 文件和目录 软链接 作为脚本, bash 脚本, bash -c 脚本, 源脚本, 或. 脚本 空间, 标签, 新闻, Unicode, 等 在目录和 / 或 文件名 Filenames 从一个 hyphen

如果您正在运行从Linux,似乎使用proc操作是找到目前运行脚本的完全解决源的最佳解决方案(在互动会议中,链接点到相应的 /dev/pts/X):

resolved="$(readlink /proc/$$/fd/255 && echo X)" && resolved="${resolved%$'\nX'}"

absolute_path=$(readlink -e -- "${BASH_SOURCE[0]}" && echo x) && absolute_path=${absolute_path%?x}
dir=$(dirname -- "$absolute_path" && echo x) && dir=${dir%?x}
file=$(basename -- "$absolute_path" && echo x) && file=${file%?x}

ls -l -- "$dir/$file"
printf '$absolute_path: "%s"\n' "$absolute_path"