如何将当前工作目录设置为脚本目录?

时间:2010-07-28 00:43:29

标签: bash path scripting

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

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

13 个答案:

答案 0 :(得分:510)

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

答案 1 :(得分:288)

以下也有效:

cd "${0%/*}"

语法在this StackOverflow回答中详细描述。

答案 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 can I get the behavior of GNU's readlink -f on a Mac?

答案 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执行脚本,然后您可以看到当前的工作目录。