在与当前脚本相同的目录中运行脚本

时间:2016-08-16 15:19:01

标签: bash path filepath

我在同一个文件夹中有两个Bash脚本(由下载整个存储库的用户保存在某处):

  • script.sh由用户运行
  • helper.sh是必需的,由script.sh
  • 运行

这两个脚本应该在同一目录中。我需要第一个脚本来调用第二个脚本,但有两个问题:

  1. 了解当前的工作目录对我来说毫无用处,因为我不知道用户是如何执行第一个脚本的(可能是/usr/bin/script.sh./script.sh,或者可能是与../Downloads/repo/scr/script.sh
  2. 在调用script.sh之前,脚本helper.sh将更改为其他目录。
  3. 我绝对可以通过将the current directory存储在一个变量中来解决这个问题,但是这个代码看起来很复杂,我认为这是一个非常常见且简单的任务。

    是否有一种标准的方式可靠helper.sh内调用script.sh?并且可以在任何支持Bash的操作系统中使用吗?

4 个答案:

答案 0 :(得分:41)

由于$0包含正在运行的脚本的完整路径,因此您可以使用dirname来获取脚本的路径:

#!/bin/bash

script_name=$0
script_full_path=$(dirname "$0")

echo "script_name: $script_name"
echo "full path: $script_full_path"

因此,如果您将其存储在/tmp/a.sh中,那么您将看到如下输出:

$ /tmp/a.sh
script_name: /tmp/a.sh
full path: /tmp

所以

  
      
  1. 知道当前的工作目录对我来说没用,因为我不知道用户是如何执行第一个脚本的(可能是   /usr/bin/script.sh./script.sh,或者可能是../Downloads/repo/scr/script.sh   dirname "$0"
  2.   

使用script.sh可以跟踪原始路径。

  
      
  1. 在调用helper.sh之前,脚本$0将更改为其他目录。
  2.   

同样,由于您在cd中有路径,因此可以<head>返回该路径。

答案 1 :(得分:6)

$ 0被许多开发人员视为unsafe。我找到了另一种解决方案,对于一连串的bash脚本和 source ,它是安全的。

如果a.sh需要使用 child bash进程执行b.sh(位于同一文件夹中):

#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
bash ${__dir}/b.sh

如果a.sh需要使用相同 bash进程执行b.sh(位于同一文件夹中):

#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source ${__dir}/b.sh

答案 2 :(得分:3)

<块引用>

是否有一种标准方法可以可靠地从内部调用 helper.sh script.sh?并且可以在任何支持 Bash 的操作系统中工作吗?

大多数情况,当 helper.shscript.sh 位于同一目录中时,您可以在 script.sh 命令中使用:

. ${0%/*}/helper.sh

解释:
$0 存储您的进程的名称(在大多数情况下,它是您的脚本的完整路径)。
${parameter%word} 从变量 word 中删除后缀模式 $parameter(在上面的命令中,它从存储在变量 /* 中的完整路径中删除文件名 $0)。

如果由于某些原因(在其他答案中描述)您不想使用 $0,您可以使用 $BASH_SOURCE 代替:

. ${BASH_SOURCE%/*}/helper.sh

如果您愿意,可以使用 source 代替 .

source ${BASH_SOURCE%/*}/helper.sh

对我来说,这是实现目标的最简单方法。

答案 3 :(得分:0)

您可以使用 $0 变量。但这不会像获取当前脚本名称那么简单:

d=${0%/*}
[ x"$d" = x"$0" ] && d=.   # portable variant, use [[ ...]] in bash freely
readonly d                 # optional, for additional safety

# ... later on
. "$d"/helper.sh

这也适用于 set -e 情况。