我正在写一个bash脚本。我需要当前的工作目录始终是脚本所在的目录。
默认行为是脚本中的当前工作目录是我运行它的shell的目录,但我不想要这种行为。
答案 0 :(得分:510)
#!/bin/bash
cd "$(dirname "$0")"
答案 1 :(得分:288)
答案 2 :(得分:153)
尝试以下简单的单行:
适用于所有UNIX / OSX / Linux
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
注意:命令中使用双短划线( - )表示命令选项的结束,因此包含短划线或其他特殊字符的文件不会破坏命令。
适用于Linux,Mac和其他* BSD:
cd "$(dirname "$(realpath "$0")")";
注意:realpath
默认情况下应安装在最流行的Linux发行版中(如Ubuntu),但在某些情况下可能会丢失,因此您必须安装它。
否则你可以尝试类似的东西(它将使用第一个现有的工具):
cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"
特定于Linux:
cd "$(dirname "$(readlink -f "$0")")"
在* BSD / Mac上使用GNU readlink:
cd "$(dirname "$(greadlink -f "$0")")"
注意:您需要安装coreutils
(例如1.安装Homebrew,2。brew install coreutils
)。
在bash中
在bash中,您可以使用Parameter Expansions来实现这一目标,例如:
cd "${0%/*}"
但如果脚本是从同一目录运行则不起作用。
或者,您可以在bash中定义以下函数:
realpath () {
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
此函数需要1个参数。如果参数已经是绝对路径,则按原样打印,否则打印$PWD
变量+文件名参数(不带./
前缀)。
或者这是从Debian .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"
}
相关:
How to detect the current directory in which I run my shell script?
Get the source directory of a Bash script from within the script itself
Reliable way for a Bash script to get the full path to itself
另见:
答案 3 :(得分:58)
cd "$(dirname "${BASH_SOURCE[0]}")"
这很容易。它有效。
答案 4 :(得分:5)
可接受的答案非常适合未在其他地方进行符号链接的脚本,例如$PATH
中的脚本。
#!/bin/bash
cd "$(dirname "$0")"
但是,如果脚本是通过符号链接运行的,则
ln -sv ~/project/script.sh ~/bin/;
~/bin/script.sh
这将CD进入~/bin/
目录,而不是~/project/
目录,如果cd
的目的是包括相对于{{1}的依赖项,则可能会破坏脚本。 }
symlink安全答案如下:
~/project/
#!/bin/bash
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
是解析潜在符号链接文件的绝对路径所必需的。
需要引号支持可能包含空格的文件路径(不好的做法,但是假设情况并非如此)
答案 5 :(得分:2)
这个脚本似乎对我有用:
#!/bin/bash
mypath=`realpath $0`
cd `dirname $mypath`
pwd
pwd命令行将脚本的位置作为当前工作目录回显,无论我从哪里运行它。
答案 6 :(得分:1)
获取脚本的真实路径
if [ -L $0 ] ; then
ME=$(readlink $0)
else
ME=$0
fi
DIR=$(dirname $ME)
(这是我在这里回答的问题:Get the name of the directory where a script is executed)
答案 7 :(得分:1)
cd "`dirname $(readlink -f ${0})`"
答案 8 :(得分:1)
我接受了,它奏效了。
#!/bin/bash
cd "$(dirname "$0")"
CUR_DIR=$(pwd)
答案 9 :(得分:0)
大多数答案要么不处理通过相对路径符号链接的文件,要么不是单行文件,要么不处理 BSD (Mac)。一个解决所有三个问题的方法是:
HERE=$(cd "$(dirname "$BASH_SOURCE")"; cd -P "$(dirname "$(readlink "$BASH_SOURCE" || echo .)")"; pwd)
首先,cd 到 bash 脚本目录的概念。然后读取链接文件以查看它是否是符号链接(相对或其他),如果是,则 cd 到该目录。如果没有, cd 到当前目录(必须保持单行)。然后通过 pwd
回显当前目录。
您可以在 cd 和 readlink 的参数中添加 --
以避免出现类似选项的目录问题,但我不会为大多数目的而烦恼。
您可以在此处查看带插图的完整说明:
https://www.binaryphile.com/bash/2020/01/12/determining-the-location-of-your-script-in-bash.html
答案 10 :(得分:0)
这里有很多正确的答案,但对我来说更有用的答案(确保脚本的相对路径保持可预测/有效)是使用 pushd/popd:< /p>
pushd "$(dirname ${BASH_SOURCE:0})"
trap popd EXIT
# ./xyz, etc...
这会将源文件的目录推送到导航堆栈,从而更改工作目录,但是,当脚本退出时(无论出于何种原因,包括失败),trap
将运行 {{1} },在执行之前恢复当前工作目录。如果脚本 popd
然后失败,您的终端可能会在执行结束后处于不可预测的状态 - 陷阱会阻止这种情况发生。
答案 11 :(得分:-4)
echo $PWD
PWD是一个环境变量。
答案 12 :(得分:-5)
如果您只需要打印当前的工作目录,那么您可以按照此步骤进行操作。
$ vim test
#!/bin/bash
pwd
:wq to save the test file.
授予执行权限:
chmod u+x test
然后按./test
执行脚本,然后您可以看到当前的工作目录。