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

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


当前回答

大多数答案要么不处理通过相对路径进行符号链接的文件,要么不是一行程序,要么不处理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

其他回答

试试下面这些简单的语句:


适用于所有UNIX/OSX/Linux

dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)

Bash

dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)

注意:双破折号(——)在命令中用于表示命令选项的结束,因此包含破折号或其他特殊字符的文件不会中断命令。

注意:在Bash中,使用${BASH_SOURCE[0]}来代替$0,否则在源路径(source/.)时路径会中断。


对于Linux, Mac和其他*BSD:

cd "$(dirname "$(realpath "$0")")";

注意:默认情况下,realpath应该安装在最流行的Linux发行版中(如Ubuntu),但在某些情况下,它可能会丢失,所以你必须安装它。

注意:如果您正在使用Bash,请使用${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。安装Homebrew, 2。Brew install coreutils)。


在bash中

在bash中,你可以使用参数展开来实现这一点,比如:

cd "${0%/*}"

但是,如果脚本在同一个目录中运行,那么它就不起作用。

或者你也可以在bash中定义以下函数:

realpath () {
  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${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"
}

相关:

如何检测当前目录,我在其中运行我的shell脚本? 从脚本本身中获取Bash脚本的源目录 Bash脚本绝对路径与OS X Bash脚本获取自身完整路径的可靠方法

参见:

如何在Mac上获得GNU的readlink -f的行为?

大多数答案要么不处理通过相对路径进行符号链接的文件,要么不是一行程序,要么不处理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

这个脚本似乎对我有用:

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

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

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

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