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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39768712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:14:37  来源:igfitidea点击:

How to pass arguments to a script invoked by source command?

linuxbash

提问by Yuan Wen

I am invoking a script through sourcecommand and want to pass arguments to the script.

我正在通过source命令调用脚本并希望将参数传递给脚本。

I have checked man source, the bash returns:

我已经检查过man source,bash 返回:

: [arguments]
No effect; the command does nothing beyond expanding arguments and performing any specified redirections. A zero exit code is returned.

source filename [arguments]
Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename. If filename does not contain a slash, file names in PATH are used to find the directory containing filename. The file searched for in PATH need not be executable. When bash is not in posix mode, the current directory is searched if no file is found in PATH. If the sourcepath option to the shopt builtin command is turned off, the PATH is not searched. If any arguments are supplied, they become the positional parameters when filename is executed. Otherwise the positional parameters are unchanged. The return status is the status of the last command exited within the script (0 if no commands are executed), and false if filename is not found or cannot be read.

:[参数]
没有效果;该命令除了扩展参数和执行任何指定的重定向外,什么都不做。返回零退出代码。

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

It has no examples, so I don't understand it .

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

采纳答案by redneb

Create a file test.shwith the following contents:

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

echo "I was given $# argument(s):"
printf "%s\n" "$@"

and then source it from an interactive shell session:

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

$ source ./test.sh a 'b c'
I was given 2 argument(s):
a
b c

so you access the arguments just like you would do in a regular bash script, with $@or $1, $2, $3, etc.

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

For comparison, run it as a regular script:

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

$ bash ./test.sh a 'b c'
I was given 2 argument(s):
a
b c

回答by Alexander Samoylov

Bourne shell and some other shells ignore the parameters passed to "." (see https://unix.stackexchange.com/questions/5024/passing-variables-to-a-bash-script-when-sourcing-it).

Bourne shell 和其他一些 shell 会忽略传递给“.”的参数。(参见https://unix.stackexchange.com/questions/5024/passing-variables-to-a-bash-script-when-sourcing-it)。

I can propose one workaround. Let imagine the script which you want to source looks like this:

我可以提出一种解决方法。假设您要获取的脚本如下所示:

$ cat ./setEnv 
export BRANCH=
$ sh -c '. ./setEnv master linux; echo BRANCH=$BRANCH ; echo TARGET=$TARGET'
BRANCH=sh
TARGET=
export TARGET=

The usual way it does not work:

它不起作用的通常方式:

$ sh -c '. ./setEnv; echo BRANCH=$BRANCH ; echo TARGET=$TARGET' master linux
BRANCH=master
TARGET=linux

But if you specify the parameters after the ' ' then they will belong to the parent shell that is they will be accessible in the script which you are sourcing:

但是,如果您在 ' ' 之后指定参数,则它们将属于父 shell,即可以在您正在采购的脚本中访问它们:

##代码##

I use this way when I need a oneline-command in Bourne shell which starts from ". ./setEnv" and continues with multiple commands separated with ; or &&.

当我在 Bourne shell 中需要一个单行命令时,我会使用这种方式,该命令从“. ./setEnv”开始并继续使用多个命令分隔;或者 &&。