我通过source
命令调用脚本,并希望将参数传递给脚本。
我检查了man source
,bash返回:
:[参数]
没有效果;除扩展参数和执行任何指定的重定向之外,该命令不执行任何操作。返回零退出代码。源文件名[参数]
在当前shell环境中从filename读取并执行命令,并返回从filename执行的最后一个命令的退出状态。如果filename不包含斜杠,则使用PATH中的文件名来查找包含filename的目录。在PATH中搜索的文件不需要是可执行的。当bash不处于posix模式时,如果在PATH中找不到文件,则搜索当前目录。如果关闭shopt内置命令的sourcepath选项,则不搜索PATH。如果提供了任何参数,则在执行文件名时它们将成为位置参数。否则,位置参数不变。返回状态是脚本中退出的最后一个命令的状态(如果没有执行命令,则为0),如果找不到或无法读取文件名,则返回false。
它没有例子,所以我不明白。
答案 0 :(得分:5)
使用以下内容创建文件test.sh
:
echo "I was given $# argument(s):"
printf "%s\n" "$@"
然后从交互式shell会话中获取它:
$ source ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
因此您可以像使用$@
或$1
,$2
,$3
等常规bash脚本一样访问参数。
为了进行比较,请将其作为常规脚本运行:
$ bash ./test.sh a 'b c'
I was given 2 argument(s):
a
b c
答案 1 :(得分:2)
扩展来自 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" "$@"
源自另一个脚本 userScript.sh
,例如单线:
source test.sh
运行上述示例时:
$ bash userScript.sh a 'b c'
I was given 2 argument(s):
a
b c
test.sh
继承了 userScript.sh
位置参数...现在不是我想要的(如果我这样做了,我可以使用 source test.sh "$@"
)。
我发现以下是一个有用的解决方法:将源命令封装到 Bash 函数中。新的 userScript.sh
看起来像:
function DoSource() { source test.sh ; }
DoSource
报告:
$ bash userScript.sh a 'b c'
I was given 0 argument(s):
请注意,指定空参数 (source test.sh ''
) 并不等效,因为空参数将传递给 test.sh
。
如果 userScript.sh
本身应该是来源,那么人们可能不想留下 DoSource()
。在这种情况下,简单的解决方案是自毁:
function _userScript_sh_DoSource() { source test.sh ; unset "$FUNCNAME" ; }
_userScript_sh_DoSource
一次性使用(已选择函数名称以减少名称冲突的可能性);或者 unset _userScript_sh_DoSource
命令可以放在不再需要 _userScript_sh_DoSource
之后。
更复杂的 DoSource()
变体:
function DoSource() { local ScriptName="$1" ; shift ; source "$ScriptName" ; }
DoSource test1.sh
DoSource test1.sh "$@"
DoSource test2.sh
可以用作 source
的“插入式”替代品,唯一的区别是当没有为要获取的脚本指定位置参数时,source
会继承它们,而 { {1}} 不使用。
但请注意,DoSource
是一个函数,因此在其他方面(例如堆栈调用、DoSource
、...)的行为与 source
不同。
答案 2 :(得分:0)
Bourne外壳程序和其他一些外壳程序忽略传递给“”的参数。 (请参阅https://unix.stackexchange.com/questions/5024/passing-variables-to-a-bash-script-when-sourcing-it)。
我可以提出一种解决方法。假设您要获取的脚本看起来像这样:
$ cat ./setEnv
export BRANCH=$0
export TARGET=$1
它通常不起作用:
$ sh -c '. ./setEnv master linux; echo BRANCH=$BRANCH ; echo TARGET=$TARGET'
BRANCH=sh
TARGET=
但是,如果您在''之后指定参数,则它们将属于父外壳,可以在您正在采购的脚本中访问它们:
$ sh -c '. ./setEnv; echo BRANCH=$BRANCH ; echo TARGET=$TARGET' master linux
BRANCH=master
TARGET=linux
当我在Bourne shell中需要一个单行命令时使用这种方式,该命令以“ ../setEnv”开头,并以多个命令分隔;或&&。