如何将参数传递给source命令调用的脚本?

Yua*_*Wen 12 linux bash

我通过source命令调用脚本,并希望将参数传递给脚本.

我检查过man source,bash返回:

:[参数]
没有效果; 除扩展参数和执行任何指定的重定向之外,该命令不执行任何操作.返回零退出代码.

source filename [arguments]
从当前shell环境中的filename读取并执行命令,并返回从filename执行的最后一个命令的退出状态.如果filename不包含斜杠,则使用PATH中的文件名来查找包含filename的目录.在PATH中搜索的文件不需要是可执行的.当bash不处于posix模式时,如果在PATH中找不到文件,则搜索当前目录.如果关闭shopt内置命令的sourcepath选项,则不搜索PATH.如果提供了任何参数,则在执行文件名时它们将成为位置参数.否则,位置参数不变.返回状态是脚本中退出的最后一个命令的状态(如果没有执行命令,则为0),如果未找到或无法读取文件名,则返回false.

它没有例子,所以我不明白.

Ham*_*let 12

扩展 redneb 的(当前已接受的)答案......

TL;DR需要在另一个脚本中获取没有位置参数的脚本吗?尝试function DoSource() { source test.sh ; } ; DoSource而不只是source test.sh.

source在另一个脚本中使用不带参数的脚本

问题中的Bash手册摘录显示了如何将位置参数分配给源脚本的详细信息。特别是,如果源命令未指定任何参数,则会为其分配调用环境中的参数。

结果是,source一个脚本在另一个脚本中不传递参数可能会很麻烦。例如,让我们使用 redneb 示例test.sh

echo "I was given $# argument(s):"
printf "%s\n" "$@"
Run Code Online (Sandbox Code Playgroud)

源自另一个脚本userScript.sh,例如单行:

source test.sh
Run Code Online (Sandbox Code Playgroud)

运行上面的示例时:

$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
Run Code Online (Sandbox Code Playgroud)

test.sh继承userScript.sh位置参数...现在这不是我想要的(如果我这样做,我可以使用source test.sh "$@")。

我发现以下是一个有用的解决方法:将源命令封装到 Bash 函数中。新的userScript.sh看起来像:

$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
Run Code Online (Sandbox Code Playgroud)

报告:

$ bash userScript.sh a 'b c'
I was given 0 argument(s):

Run Code Online (Sandbox Code Playgroud)

请注意,指定空参数 ( source test.sh '') 并不等效,因为空参数将传递给test.sh.

如果还希望采购脚本

如果userScript.sh它本身应该是有来源的,那么人们可能不想留下DoSource()来。在这种情况下,简单的解决方案就是自我毁灭:

function DoSource() { source test.sh ; }
DoSource
Run Code Online (Sandbox Code Playgroud)

仅供一次性使用(选择函数名称是为了减少名称冲突的可能性);或者unset _userScript_sh_DoSource可以将命令放在_userScript_sh_DoSource不再需要的位置之后。

多种用途的灵活变体

更复杂的变体DoSource()

$ bash userScript.sh a 'b c'
I was given 0 argument(s):

Run Code Online (Sandbox Code Playgroud)

可以用作 的“直接”替代source,唯一的区别是,当没有为要获取的脚本指定位置参数时,source继承它们,而不DoSource使用任何位置参数。但请注意,这DoSource是一个函数,因此其行为与source其他方面不同(例如堆栈调用,FUNCNAME...)。


red*_*neb 7

创建test.sh包含以下内容的文件:

echo "I was given $# argument(s):"
printf "%s\n" "$@"
Run Code Online (Sandbox Code Playgroud)

然后从交互式shell会话中获取它:

$ source ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
Run Code Online (Sandbox Code Playgroud)

所以你访问这些参数,就像你做一个普通bash脚本,用$@$1,$2,$3等.

为了比较,将其作为常规脚本运行:

$ bash ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
Run Code Online (Sandbox Code Playgroud)

  • 该问题被标记为“bash”;不需要符合 POSIX 标准的答案。 (5认同)
  • script!= bash :(.这不适用于POSIX兼容的shell(破折号). (4认同)
  • 虽然这不是必需的,但请注意:我们必须生活在混合 shell 环境中,很高兴知道这不兼容 POSIX,而仅兼容 BASH(/ZSH/KSH/...)。 (4认同)