我正在调用一些将VARIABLE
设置为某个值并返回另一个值的函数。我需要保留VARIABLE
的值,并将函数的返回值分配给另一个VAR
。这是我试过的:
bar() {
VAR="$(foo)"
echo $VARIABLE >&2
echo $VAR >&2
}
foo() {
VARIABLE="test"
echo "retval"
}
bar
但它打印
retval
有办法吗?
答案 0 :(得分:3)
ksh
有一个方便的非子shelling命令替换构造:
#!/bin/ksh
foo() {
echo "cat"
variable="dog"
}
output="${ foo }"
echo "Output is $output and the variable is $variable"
在bash
和其他shell中,您必须通过临时文件来代替:
#!/bin/bash
foo() {
echo "cat"
variable="dog"
}
# Create a temp file and register it for autodeletion
file="$(mktemp)"
trap 'rm "$file"' EXIT
# Redirect to it and read it back
foo > "$file"
output="$(< "$file")
echo "Output is $output and the variable is $variable"
答案 1 :(得分:3)
BASH不像传统函数式编程语言那样向调用者返回值。 BASH函数唯一可以返回的(本质上)是函数的“退出代码”。
要启用函数以向另一个函数提供结果,您应该使用全局变量。默认情况下,除非另有说明,否则所有变量都是全局变量。
这是一组带有一些echo语句的函数,可以帮助你理解这一点:
#!/bin/bash
export VARIABLE=""
bar() {
echo ">>> In function bar() ... "
echo " _var :: $_var"
echo " VARIABLE :: $VARIABLE"
echo ">>> Setting '_var' to value 'local to bar' ... "
local _var="local to bar"
echo ">>> calling function foo() ... "
foo
echo ">>> Back in function bar() ... "
echo " _var :: $_var"
echo " VARIABLE :: $VARIABLE"
}
foo() {
echo ">>> In function foo() ... "
local _var="local to foo"
VARIABLE="I'm a global variable"
echo " _var :: $_var"
echo " VARIABLE :: $VARIABLE"
}
bar
在上面的例子中,我们将“_var”变量设置为范围内的本地变量。当“bar()”出现时,我们将本地“_var”的值设置为“local to bar”。我们随后调用函数“foo()”;它将局部变量“_var”设置为“local to foo”。
我们还将全局变量“VARIABLE”设置为“我是全局变量”的值。
当执行返回“bar()”函数时,我们打印VARIABLE和_var。 VARIABLE导致字符串“我是一个全局变量”。
有关BASH中函数的返回值的详细信息,请参阅问题Return value in a Bash function。
以上是上述结果:
>>> In function bar() ...
_var ::
VARIABLE ::
>>> Setting '_var' to value 'local to bar' ...
>>> calling function foo() ...
>>> In function foo() ...
_var :: local to foo
VARIABLE :: I'm a global variable
>>> Back in function bar() ...
_var :: local to bar
VARIABLE :: I'm a global variable
请注意,我们从未在“bar()”函数中设置VARIABLE的值。它在“foo()”中设置,随后,我们使用全局变量访问结果。
局部变量“_var”也说明这些值只是每个函数的“本地”,并且通过指定它们是本地的,它们在函数本身之外没有任何值或含义。
您可以使用子shell来执行您想要的操作。但是,子壳在单独的处理空间中运行,因此您经常会遇到意想不到的副作用。要在子shell示例中使用:
#!/bin/bash
export VARIABLE="default global value"
function bar()
{
VAR=$(foo)
echo "VARIABLE :: $VARIABLE"
echo " VAR :: $VAR"
}
function foo()
{
# in theory, VARIABLE is globally scoped, but called in a
# subshell, it won't impact/change the calling environment
export VARIABLE='test'
echo "$VARIABLE"
}
bar
尽管以这种方式通过子shell捕获输出仍然有效 - 如果您的函数返回或输出多个值,您最终可能会遇到您不想要的奇怪行为。上面的例子说明了对函数的随意观察表明“foo()”会改变全局范围内“VARIABLE”的值。但是因为它是在子shell('$(foo)')中运行的 - 它实际上根本不会改变全局VARIABLE值。
这可能会导致较大的脚本中存在细微的逻辑错误,我建议不要使用此方法。以下是上述代码段的输出:
VARIABLE :: default global vaule
VAR :: test
答案 2 :(得分:3)
嗯,这可能很难看,但是 -
在bash中,除非声明local
,否则所有变量都是全局变量。因此,您可以直接在VAR
中分配foo
:
bar() {
#### VAR="$(foo)"
foo # Just call it
echo $VARIABLE >&2
echo $VAR >&2
}
foo() {
VARIABLE="test"
#### echo "retval"
VAR="retval" # What would have gone in $VAR before
}
bar
输出:
test
retval