Tim*_*ske 10 bash source shell-builtin
鉴于以下来源的barBash 脚本......
echo :$#:"$@":
Run Code Online (Sandbox Code Playgroud)
...以及以下可执行的fooBash 脚本:
echo -n source bar:
source bar
echo -n source bar foo:
source bar foo
function _import {
source "$@"
}
echo -n _import bar:
_import bar
echo -n _import bar foo:
_import bar foo
Run Code Online (Sandbox Code Playgroud)
运行fooBash 脚本时,我得到以下输出,即./foo:
source bar::0::
source bar foo::1:foo:
_import bar::1:bar:
_import bar foo::1:foo:
Run Code Online (Sandbox Code Playgroud)
以下是我的问题:
source从_import函数中调用 Bash 的命令而不是直接调用时,为什么会有所不同?source命令的行为?我在 Fedora 版本 20 上使用 Bash 版本 4.2.47(1)-release。
问题是因为source在当前环境中执行文件。而在 中bash,如果没有提供位置参数,则它们不变。来自bash Bourne Shell Builtins手册页:
. (一段时间)
. 文件名 [参数]
从当前 shell 上下文中的 filename 参数读取和执行命令。如果文件名不包含斜杠,则使用 PATH 变量来查找文件名。当 Bash 不处于 POSIX 模式时,如果在 $PATH 中找不到文件名,则搜索当前目录。如果提供了任何参数,它们将在执行 filename 时成为位置参数。否则位置参数不变。返回状态是最后执行的命令的退出状态,如果没有执行命令,则为零。如果找不到文件名或无法读取文件名,则返回状态为非零。这个内置函数等同于 source。
POSIX 定义了点(source是dotin 的同义词bash):
shell 应从当前环境中的文件执行命令。
它还解释了 KornShell 版本的 dot 可以采用可选参数,这些参数设置为位置参数:
dot 的 KornShell 版本采用设置为位置参数的可选参数。这是一个有效的扩展,它允许点脚本与函数的行为相同。
所以当你调用source bar内部_import函数时,你不提供任何位置参数,所以它们是不变的。它们与_import函数作用域相同,$@包含bar和$#是1(因为你运行_import bar)。
当您source bar在_import函数作用域之外调用时,它与全局作用域(或foo脚本)相同。在这种情况下,因为您 run ./foo,所以您在foo没有任何参数的情况下运行,$@为 null 且$#为零。
Gnouc 的回答解释了我的第一个问题:“为什么我从 _import 函数调用 Bash 的源命令而不是直接调用它会有所不同?”
关于我的第二个问题:“如何规范 Bash 源命令的行为?”
我想我找到了以下答案:
通过将_import函数更改为:
function _import {
local -r file="$1"
shift
source "$file" "$@"
}
Run Code Online (Sandbox Code Playgroud)
运行fooBash 脚本时,我得到以下输出,即./foo:
source bar::0::
source bar foo::1:foo:
_import bar::0::
_import bar foo::1:foo:
Run Code Online (Sandbox Code Playgroud)
我的问题和这个答案背后的基本原理:“导入的”Bash 脚本应该能够通过 Bash 的位置参数和特殊参数来评估它自己的参数集,即使在导入时没有给出任何参数。任何可以传递给导入 Bash 脚本的参数不得隐式传递给导入的 Bash 脚本。
| 归档时间: |
|
| 查看次数: |
13661 次 |
| 最近记录: |