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

IQA*_*eas 39 bash path filepath

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

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

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

  1. 知道当前的工作目录对我来说是无用的,因为我不知道用户是如何执行第一个脚本的(可能是with /usr/bin/script.sh,with ./script.sh或者它可能是../Downloads/repo/scr/script.sh)
  2. script.sh在调用之前,脚本将更改为其他目录helper.sh.

我绝对可以通过将当前目录存储在一个变量中来实现这一目的,但是该代码似乎不必要地复杂化,因为我认为这是一个非常常见且简单的任务.

可靠的helper.sh内部可靠呼叫方式script.sh吗?并且可以在任何支持Bash的操作系统中使用吗?

fed*_*qui 46

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

#!/bin/bash

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

echo "script_name: $script_name"
echo "full path: $script_full_path"
Run Code Online (Sandbox Code Playgroud)

所以,如果您将其存储在那里,/tmp/a.sh那么您将看到如下输出:

$ /tmp/a.sh
script_name: /tmp/a.sh
full path: /tmp
Run Code Online (Sandbox Code Playgroud)

所以

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

使用dirname "$0"将允许您跟踪原始路径.

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

再说一遍,因为你有路径,$0你可以cd回到它.

  • 简而言之,在脚本源中使用`$ 0`不能正常工作。对于bash,有`BASH_SOURCE`选项。 (6认同)
  • 使用`$ 0`显然是[不安全](https://mywiki.wooledge.org/BashFAQ/028) (4认同)

Iva*_*sky 15

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

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

. ${0%/*}/helper.sh
Run Code Online (Sandbox Code Playgroud)

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

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

. ${BASH_SOURCE%/*}/helper.sh
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你可以使用source而不是.

source ${BASH_SOURCE%/*}/helper.sh
Run Code Online (Sandbox Code Playgroud)

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


Eug*_*gen 9

$ 0被许多开发人员认为是不安全的。我找到了另一个解决方案,对于一连串的bash脚本和source来说是安全的。

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

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

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

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