DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 的作用是什么?

72
我需要获取脚本的路径。如果我已经在同一目录中,可以使用pwd命令来获取路径。我在网上搜索并找到了以下内容:DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )",但我不知道如何使用它。

你试过了吗,即echo“script=$0 dirForScript=$DIR"?你应该展示一下你尝试解决问题的努力。如果你把你的DIR=...代码和我的echo script=...放进一个脚本中,并从不同的目录调用主脚本,你应该可以看到相同的结果。如果不行,那就有趣了,你可以更新一下你的问题,说明为什么它“不起作用”。祝好运。 - shellter
所以,我现在在我的脚本文件中有以下代码: #!/usr/bin/env bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" echo "script=$0 dirForScript=$DIR我试图从不同的目录运行它,但是它显示:-bash: Send-Transaction.sh:找不到命令 - Alex Bloomberg
我使用 sh filename.sh 运行。我做错了什么还是全部都错了? - Alex Bloomberg
尝试运行 sh /full/path/to/filename.sh。那应该可以工作。然后您需要将 /full/path/to 添加到您的 PATH 环境变量中。对于这么简单的事情,一开始可能会非常令人困惑。不要放弃,但找到一个好的 Linux 教程并阅读关于 PATH 的如何/为什么的内容。祝你好运。(我要去睡觉了;-)。 - shellter
但是当我已经知道文件名的完整路径时,那还有什么用呢? - Alex Bloomberg
2个回答

97

Bash维护了许多变量,包括 BASH_SOURCE,它是源文件路径名的数组。

${} 作为一种变量引用方式。

$() 作为一种命令引用方式,但它们在自己的上下文中运行。

dirname 返回所提供参数的路径部分。

cd 更改当前目录。

pwd 显示当前路径。

&& 是逻辑与运算符,但在此实例中用于依次运行多个命令。

总之,该命令获取脚本的源文件路径名,将其剥离为仅路径部分,cd 到该路径,然后使用 pwd 返回(实际上)脚本的完整路径。这被分配给 DIR。完成所有操作后,环境被还原,因此您会回到起始目录,但会有一个名为 DIR 的环境变量,其中包含脚本的路径。


4
它只是让脚本知道它自己的位置,而不是你当前的位置。如果你只需要在运行脚本时获取当前所在位置,那就简单多了:DIR="$( pwd )" - Ouroborus
1
如果脚本知道自己的位置,有什么优势?如果不知道,是否有区别?脚本仍然可以工作。 - Alex Bloomberg
1
这是我的最后一个问题,我保证! - Alex Bloomberg
3
我认为这个答案也应该解释一下为什么要使用${BASH_SOURCE[0]}而不是${BASH_SOURCE}。否则就很完美了。 - Bruno Bronosky
5
https://www.electrictoolbox.com/bash-script-directory/ 这篇文章详细介绍了这种方法与基本选项 dirname $0 的区别(即只使用 shell 内置命令确保路径是绝对路径,具体讨论见 https://dev59.com/gm865IYBdhLWcg3wOcHy#3915420 及该问题的其他答案)。 - ncoghlan
显示剩余10条评论

0

让我们来分解一下:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

  • ${BASH_SOURCE[0]}:将解析为从命令行调用脚本的脚本名称(您需要使用${}来清晰地访问数组)
  • "$( dirname "${BASH_SOURCE[0]}" )":将解析为其目录部分
    • dirname "/foo/bar" 给出 "/foo"
    • "(引号)处理其中有空格的情况(文件名和路径中都有)
    • $(command) 将调用该命令并将stdout返回到变量中

这个第一部分有一些限制。如果通过链接调用您的脚本,则会收到链接的目录名称,而不是脚本的目录名称。这可能没问题。但是,如果您想要源另一个文件(比如说一个库),则该文件位于您的真实脚本旁边。要找到真实路径,您需要更多的内容:

  • $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ):将解析出脚本的真实路径。

如何使用?

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$DIR"/lib.sh

什么不应该做?

pwd:只有当您始终从当前文件夹启动脚本时,它才有效。这对于某些系统脚本可能有效,但通常情况下,您不会这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接