#!/bin/bash mypath=`realpath $0` cd `dirname $mypath` pwd
#!/bin/bash cd "$(dirname "$0")"
if [ -L $0 ] ; then ME=$(readlink $0) else ME=$0 fi DIR=$(dirname $ME)
cd "$(dirname "${BASH_SOURCE[0]}")"
cd "${0%/*}"
$ vim test #!/bin/bash pwd :wq to save the test file.
chmod u+x test
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
对于Linux,Mac和其他*BSD:
cd "$(dirname "$(realpath "$0")")";
注意:默认情况下,realpath应该安装在最流行的Linux发行版(如Ubuntu)中,但在某些发行版中可能会丢失,因此您必须安装它。
realpath
注意:如果您使用的是Bash,请使用${BASH_SOURCE[0]}而不是$0,否则路径在获取时可能会中断(source/.)。
${BASH_SOURCE[0]}
$0
source
.
否则,您可以尝试类似的东西(它将使用第一个现有工具):
cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"
具体Linux:
cd "$(dirname "$(readlink -f "$0")")"
在*BSD/Mac上使用GNU readlink:
cd "$(dirname "$(greadlink -f "$0")")"
注意:您需要安装coreutils (例如1.安装自制,2.brew install coreutils)。
coreutils
brew install coreutils
在bash
在bash中,您可以使用参数扩展来实现这一点,例如:
但如果脚本从同一目录运行,则不起作用。
或者,您可以在bash中定义以下函数:
realpath () { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" }
此函数接受1个参数。如果参数已经有绝对路径,请按原样打印,否则打印$PWD变量+文件名参数(没有./前缀)。
$PWD
./
或者这是来自Debian.bashrc文件的版本:
.bashrc
function realpath() { f=$@ if [ -d "$f" ]; then base="" dir="$f" else base="/$(basename "$f")" dir=$(dirname "$f") fi dir=$(cd "$dir" && /bin/pwd) echo "$dir$base" }
相关:
如何检测我运行外壳脚本的当前目录?
从脚本本身获取Bash脚本的源目录
使用OS X的Bash脚本绝对路径
Bash脚本获取自身完整路径的可靠方法
另见:
如何在Mac上获取GNU的readlink-f的行为?
cd "`dirname $(readlink -f ${0})`"
echo $PWD
PWD是一个环境变量。
接受的答案适用于其他地方没有符号链接的脚本,例如$PATH。
$PATH
但是,如果脚本通过符号链接运行,
ln -sv ~/project/script.sh ~/bin/; ~/bin/script.sh
这将cd到~/bin/目录而不是~/project/目录,如果cd的目的是包含相对于~/project/的依赖项,这可能会破坏您的脚本
~/bin/
~/project/
cd
符号链接安全答案如下:
#!/bin/bash cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" # cd current directory
readlink -f需要解析潜在符号链接文件的绝对路径。
readlink -f
需要引号来支持可能包含空格的文件路径(不好的做法,但假设情况并非如此并不安全)
我拿了这个,它起作用了。
#!/bin/bash cd "$(dirname "$0")" CUR_DIR=$(pwd)
大多数答案要么不处理通过相对路径符号链接的文件,要么不是单行程序,要么不处理BSD(Mac)。完成所有这三个的解决方案是:
HERE=$(cd "$(dirname "$BASH_SOURCE")"; cd -P "$(dirname "$(readlink "$BASH_SOURCE" || echo .)")"; pwd)
首先,cd到bash对脚本目录的概念。然后重新链接文件以查看它是否是符号链接(相对或其他),如果是,cd到该目录。如果不是,cd到当前目录(保持单行代码所必需的)。然后通过pwd回显当前目录。
pwd
您可以将--添加到cd和readlink的参数中,以避免类似选项的目录问题,但我不会为大多数目的而烦恼。
--
你可以在这里看到完整的解释和插图:
https://www.binaryphile.com/bash/2020/01/12/determining-the-location-of-your-script-in-bash.html
这里有很多正确的答案,但对我来说更有用的一个(确保脚本的相对路径保持可预测/有效)是使用pushd/popd:
pushd "$(dirname ${BASH_SOURCE:0})" trap popd EXIT # ./xyz, etc...
这会将源文件的目录推送到导航堆栈上,从而更改工作目录,但随后,当脚本退出时(无论出于何种原因,包括失败),trap将运行popd,恢复当前工作目录在它执行之前。如果脚本转到cd然后失败,你的终端可能会在执行结束后处于不可预测的状态——陷阱可以防止这种情况。
trap
popd