我想从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)
当前回答
以上所有答案都忽略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下,这个脚本也做同样的事情!
其他回答
您可以回显字符串,但通过将函数(|)连接到其他函数来捕获它。
您可以使用expr来实现,不过ShellCheck报告这种用法已弃用。
Bash自2014年2月4.3版(?)起,除了“eval”之外,还明确支持引用变量或名称引用(namerefs),具有相同的性能和间接效果,并且在你的脚本中可能更清晰,也更难“忘记'eval'而不得不修复此错误”:
declare [-aAfFgilnrtux] [-p] [name[=value] ...]
typeset [-aAfFgilnrtux] [-p] [name[=value] ...]
Declare variables and/or give them attributes
...
-n Give each name the nameref attribute, making it a name reference
to another variable. That other variable is defined by the value
of name. All references and assignments to name, except for⋅
changing the -n attribute itself, are performed on the variable
referenced by name's value. The -n attribute cannot be applied to
array variables.
...
When used in a function, declare and typeset make each name local,
as with the local command, unless the -g option is supplied...
还有:
PARAMETERS A variable can be assigned the nameref attribute using the -n option to the declare or local builtin commands (see the descriptions of declare and local below) to create a nameref, or a reference to another variable. This allows variables to be manipulated indirectly. Whenever the nameref variable is⋅ referenced or assigned to, the operation is actually performed on the variable specified by the nameref variable's value. A nameref is commonly used within shell functions to refer to a variable whose name is passed as an argument to⋅ the function. For instance, if a variable name is passed to a shell function as its first argument, running declare -n ref=$1 inside the function creates a nameref variable ref whose value is the variable name passed as the first argument. References and assignments to ref are treated as references and assignments to the variable whose name was passed as⋅ $1. If the control variable in a for loop has the nameref attribute, the list of words can be a list of shell variables, and a name reference will be⋅ established for each word in the list, in turn, when the loop is executed. Array variables cannot be given the -n attribute. However, nameref variables can reference array variables and subscripted array variables. Namerefs can be⋅ unset using the -n option to the unset builtin. Otherwise, if unset is executed with the name of a nameref variable as an argument, the variable referenced by⋅ the nameref variable will be unset.
例如(EDIT 2:(谢谢你Ron)在函数内部变量名的命名空间(前缀),以最小化外部变量冲突,这最终应该正确地回答了Karsten在评论中提出的问题):
# $1 : string; your variable to contain the return value
function return_a_string () {
declare -n ret=$1
local MYLIB_return_a_string_message="The date is "
MYLIB_return_a_string_message+=$(date)
ret=$MYLIB_return_a_string_message
}
测试这个例子:
$ return_a_string result; echo $result
The date is 20160817
请注意,bash“declare”内置在函数中使用时,默认情况下会使声明的变量为“local”,并且“-n”也可以与“local”一起使用。
我更喜欢区分“重要的声明”变量和“无聊的本地”变量,因此以这种方式使用“声明”和“本地”作为文档。
编辑1 -(对Karsten下面的评论的回应)-我不能再在下面添加评论了,但Karsten的评论让我思考,所以我做了以下测试,工作良好,AFAICT - Karsten如果你读了这篇文章,请从命令行提供一组准确的测试步骤,显示你假设存在的问题,因为以下步骤工作得很好:
$ return_a_string ret; echo $ret
The date is 20170104
(我刚刚将上面的函数粘贴到bash术语中后运行了这个程序——正如您所看到的,结果运行得很好。)
以上所有答案都忽略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下,这个脚本也做同样的事情!
你可以使用一个全局变量:
declare globalvar='some string'
string ()
{
eval "$1='some other string'"
} # ---------- end of function string ----------
string globalvar
echo "'${globalvar}'"
这给了
'some other string'
在我的程序中,按照约定,这就是预先存在的$REPLY变量的用途,read正是为此目的而使用它。
function getSomeString {
REPLY="tadaa"
}
getSomeString
echo $REPLY
这种回声
tadaa
但是为了避免冲突,任何其他全局变量都可以。
declare result
function getSomeString {
result="tadaa"
}
getSomeString
echo $result
如果这还不够,我推荐Markarian451的解决方案。