gpt4 book ai didi

bash - 采购 bash 脚本时避免命令行参数传播

转载 作者:行者123 更新时间:2023-12-02 00:04:23 26 4
gpt4 key购买 nike

我有一个如下所示的 bash 脚本 a.sh:

#!/bin/bash
echo $#
echo $1

和一个如下所示的脚本 b.sh:

#!/bin/bash
source ./a.sh

如果我调用 ./a.sh,我会正确地得到 0 和一个空行作为输出。调用 ./a.sh blabla 时,我得到 1 和 blabla 作为输出。

然而,当我调用 ./b.sh blabla 时,我也得到 1 和 blabla 作为输出,即使没有参数从内部传递给 a.sh b.sh.

这似乎与 source 的使用有关(我必须使用它,因为在我的实际用例中,a.sh 导出了一些变量)。如何避免将来自 b.sh 的参数传播到 a.sh?我考虑过使用 eval $(a.sh) 但这会使我在 a.sh 中的 echo 语句失败。我想在调用 a.sh 之前使用 shift 来消耗来自 b.sh 的参数,但我不一定知道那里有多少参数是。

最佳答案

问题的根源是 source 命令的工作方式异常。来自bash man page ,在“Shell 内置命令”部分:

. filename [arguments]
source filename [arguments]
[...] If any arguments are supplied, they become the positional parameters when filename is executed. Otherwise the positional parameters are unchanged.

...这意味着您可以通过向 sourced 脚本提供不同的参数来覆盖主脚本的参数,但是您不能只是不传递参数给它.

幸运的是,有一个解决方法;只是在没有参数的上下文中 source 脚本:

#!/bin/bash
wrapperfunction() {
source ./a.sh
}
wrapperfunction

因为没有参数提供给wrapperfunction,所以里面的参数列表是空的。由于 a.sh 的命令在该上下文中运行,因此 arg 列表在那里也是空的。在 a.sh 内部分配的变量在函数外部可用(除非它们被声明为 local 或类似的东西)。

(注意:我在 bash、zsh、dash 和 ksh93 中对此进行了测试,它在所有这些工具中都有效——好吧,除了 dash 没有 source 命令,所以你必须使用 . 代替。)

更新:我意识到你可以编写一个通用的包装函数,它允许你指定一个文件名作为参数:

sourceWithoutArgs() {
local fileToSource="$1"
shift
source "$fileToSource"
}
sourceWithoutArgs ./a.sh

shift 命令从函数的 arg 列表中删除文件名,因此当文件实际获取时它是空的。好吧,除非你向函数传递了额外的参数,在这种情况下那些在arg列表中并被传递......所以你实际上可以使用这个函数来替换没有参数的两个以及 source 的 with-args 用法。

(这适用于 bash 和 zsh。如果你想在 ksh 中使用它,你必须删除 local;要在 dash 中使用它,将 source 替换为.)

关于bash - 采购 bash 脚本时避免命令行参数传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61103034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com