我正在写一个Bash脚本。我需要当前工作目录始终是脚本所在的目录。

默认行为是脚本中的当前工作目录是我从中运行它的shell的目录,但我不想要这种行为。


当前回答

我吃了这个,它起作用了。

#!/bin/bash
cd "$(dirname "$0")"
CUR_DIR=$(pwd)

其他回答

#!/bin/bash
cd "$(dirname "$0")"

这个脚本似乎对我有用:

#!/bin/bash
mypath=`realpath $0`
cd `dirname $mypath`
pwd

无论从哪里运行,pwd命令行都将脚本的位置返回为当前工作目录。

cd "$(dirname "${BASH_SOURCE[0]}")"

很容易。它的工作原理。

这里有很多正确答案,但有一个对我来说更有用(确保脚本的相对路径保持可预测/工作)是使用pushd/popd:

pushd "$(dirname ${BASH_SOURCE:0})"
trap popd EXIT

# ./xyz, etc...

这将把源文件的目录推到导航堆栈上,从而改变工作目录,但是,当脚本退出时(无论出于什么原因,包括失败),trap将运行popd,恢复执行前的当前工作目录。如果脚本被cd,然后失败,那么在执行结束后,您的终端可能会处于一种不可预知的状态——陷阱可以防止这种情况。

接受的答案适用于没有符号链接到其他地方的脚本,例如到$PATH。

#!/bin/bash
cd "$(dirname "$0")"

然而,如果脚本是通过符号链接运行的,

ln -sv ~/project/script.sh ~/bin/; 
~/bin/script.sh

这将cd到~/bin/目录,而不是~/project/目录,如果cd的目的是包含相对于~/project/的依赖项,这可能会破坏您的脚本

符号链接安全的答案如下:

#!/bin/bash
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"  # cd current directory

需要Readlink -f来解析潜在符号链接文件的绝对路径。

需要引号来支持可能包含空格的文件路径(不好的做法,但假设情况不是这样也不安全)