我在同一个文件夹中有两个Bash脚本(由下载整个存储库的用户保存在某处):
script.sh
由用户运行helper.sh
是必需的,由script.sh
这两个脚本应该在同一目录中。我需要第一个脚本来调用第二个脚本,但有两个问题:
/usr/bin/script.sh
,./script.sh
,或者可能是与../Downloads/repo/scr/script.sh
)script.sh
之前,脚本helper.sh
将更改为其他目录。我绝对可以通过将the current directory存储在一个变量中来解决这个问题,但是这个代码看起来很复杂,我认为这是一个非常常见且简单的任务。
是否有一种标准的方式可靠从helper.sh
内调用script.sh
?并且可以在任何支持Bash的操作系统中使用吗?
答案 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
所以
- 知道当前的工作目录对我来说没用,因为我不知道用户是如何执行第一个脚本的(可能是
醇>/usr/bin/script.sh
,./script.sh
,或者可能是../Downloads/repo/scr/script.sh
dirname "$0"
)
使用script.sh
可以跟踪原始路径。
- 在调用
醇>helper.sh
之前,脚本$0
将更改为其他目录。
同样,由于您在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.sh
与 script.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
情况。