我想从Bash函数返回一个字符串。
我将用java写这个例子来说明我想做什么:
public String getSomeString() {
return "tadaa";
}
String variable = getSomeString();
下面的示例可以在bash中工作,但是是否有更好的方法来做到这一点?
function getSomeString {
echo "tadaa"
}
VARIABLE=$(getSomeString)
我想从Bash函数返回一个字符串。
我将用java写这个例子来说明我想做什么:
public String getSomeString() {
return "tadaa";
}
String variable = getSomeString();
下面的示例可以在bash中工作,但是是否有更好的方法来做到这一点?
function getSomeString {
echo "tadaa"
}
VARIABLE=$(getSomeString)
当前回答
像上面的bstpierre一样,我使用并推荐使用显式命名输出变量:
function some_func() # OUTVAR ARG1
{
local _outvar=$1
local _result # Use some naming convention to avoid OUTVARs to clash
... some processing ....
eval $_outvar=\$_result # Instead of just =$_result
}
注意引用$的用法。这将避免将$result中的内容解释为shell特殊字符。我发现这比result=$(some_func "arg1")捕获回声的习惯用法快一个数量级。在MSYS上使用bash时,速度差异似乎更加显著,从函数调用中捕获标准输出几乎是灾难性的。
可以发送一个局部变量,因为局部变量在bash中是动态作用域的:
function another_func() # ARG
{
local result
some_func result "$1"
echo result is $result
}
其他回答
以上所有答案都忽略bash手册页中所述内容。
函数中声明的所有变量都将与调用环境共享。 所有在本地声明的变量将不会被共享。
示例代码
#!/bin/bash
f()
{
echo function starts
local WillNotExists="It still does!"
DoesNotExists="It still does!"
echo function ends
}
echo $DoesNotExists #Should print empty line
echo $WillNotExists #Should print empty line
f #Call the function
echo $DoesNotExists #Should print It still does!
echo $WillNotExists #Should print empty line
和输出
$ sh -x ./x.sh
+ echo
+ echo
+ f
+ echo function starts
function starts
+ local 'WillNotExists=It still does!'
+ DoesNotExists='It still does!'
+ echo function ends
function ends
+ echo It still 'does!'
It still does!
+ echo
同样在pdksh和ksh下,这个脚本也做同样的事情!
像上面的bstpierre一样,我使用并推荐使用显式命名输出变量:
function some_func() # OUTVAR ARG1
{
local _outvar=$1
local _result # Use some naming convention to avoid OUTVARs to clash
... some processing ....
eval $_outvar=\$_result # Instead of just =$_result
}
注意引用$的用法。这将避免将$result中的内容解释为shell特殊字符。我发现这比result=$(some_func "arg1")捕获回声的习惯用法快一个数量级。在MSYS上使用bash时,速度差异似乎更加显著,从函数调用中捕获标准输出几乎是灾难性的。
可以发送一个局部变量,因为局部变量在bash中是动态作用域的:
function another_func() # ARG
{
local result
some_func result "$1"
echo result is $result
}
提醒薇姬·罗嫩,考虑一下下面的代码
function use_global
{
eval "$1='changed using a global var'"
}
function capture_output
{
echo "always changed"
}
function test_inside_a_func
{
local _myvar='local starting value'
echo "3. $_myvar"
use_global '_myvar'
echo "4. $_myvar"
_myvar=$( capture_output )
echo "5. $_myvar"
}
function only_difference
{
local _myvar='local starting value'
echo "7. $_myvar"
local use_global '_myvar'
echo "8. $_myvar"
local _myvar=$( capture_output )
echo "9. $_myvar"
}
declare myvar='global starting value'
echo "0. $myvar"
use_global 'myvar'
echo "1. $myvar"
myvar=$( capture_output )
echo "2. $myvar"
test_inside_a_func
echo "6. $_myvar" # this was local inside the above function
only_difference
将会给
0. global starting value
1. changed using a global var
2. always changed
3. local starting value
4. changed using a global var
5. always changed
6.
7. local starting value
8. local starting value
9. always changed
也许正常的场景是使用test_inside_a_func函数中使用的语法,因此在大多数情况下可以同时使用这两种方法,尽管捕获输出是在任何情况下都能工作的更安全的方法,它模仿在其他语言中可以找到的函数的返回值,Vicky Ronnen正确地指出了这一点。
在我的程序中,按照约定,这就是预先存在的$REPLY变量的用途,read正是为此目的而使用它。
function getSomeString {
REPLY="tadaa"
}
getSomeString
echo $REPLY
这种回声
tadaa
但是为了避免冲突,任何其他全局变量都可以。
declare result
function getSomeString {
result="tadaa"
}
getSomeString
echo $result
如果这还不够,我推荐Markarian451的解决方案。
您还可以捕获函数输出:
#!/bin/bash
function getSomeString() {
echo "tadaa!"
}
return_var=$(getSomeString)
echo $return_var
# Alternative syntax:
return_var=`getSomeString`
echo $return_var
看起来很奇怪,但比使用全局变量更好。传递参数和往常一样,只是把它们放在大括号或反勾号内。