我想从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模式返回标量和数组值对象:
定义
url_parse() { # parse 'url' into: 'url_host', 'url_port', ...
local "$@" # inject caller 'url' argument in local scope
local url_host="..." url_path="..." # calculate 'url_*' components
declare -p ${!url_*} # return only 'url_*' object fields to the caller
}
调用
main() { # invoke url parser and inject 'url_*' results in local scope
eval "$(url_parse url=http://host/path)" # parse 'url'
echo "host=$url_host path=$url_path" # use 'url_*' components
}
其他回答
为了说明我对Andy的回答的评论,使用额外的文件描述符操作来避免使用/dev/tty:
#!/bin/bash
exec 3>&1
returnString() {
exec 4>&1 >&3
local s=$1
s=${s:="some default string"}
echo "writing to stdout"
echo "writing to stderr" >&2
exec >&4-
echo "$s"
}
my_string=$(returnString "$*")
echo "my_string: [$my_string]"
不过还是很恶心。
你可以使用一个全局变量:
declare globalvar='some string'
string ()
{
eval "$1='some other string'"
} # ---------- end of function string ----------
string globalvar
echo "'${globalvar}'"
这给了
'some other string'
虽然有很多很好的答案,但它们都不是我想要的方式。下面是我的解决方案,要点如下:
帮助健忘的程序员
至少我会努力记住错误检查之后,像这样:
允许用换行字符\n赋值
有些解决方案不允许这样做,因为有些解决方案忘记了要赋值周围的单引号。正确的方法:eval "${returnVariable}='${value}'"或者更好:参见下面的下一点。
使用printf代替eval
只需尝试使用类似myFunction "date && var2"的东西来解决这里的一些假定的解决方案。Eval会执行给它的任何东西。我只想分配值,所以我使用printf -v "${returnVariable}" "%s" "${value}"代替。
对变量名冲突的封装和保护
如果一个不同的用户或至少是对函数了解较少的人(这可能是几个月后的我)正在使用myFunction,我不希望他们知道他必须使用全局返回值名称或禁止使用某些变量名称。这就是为什么我在myFunction的顶部添加了一个名称检查:
if [[ "${1}" = "returnVariable" ]]; then
echo "Cannot give the ouput to \"returnVariable\" as a variable with the same name is used in myFunction()!"
echo "If that is still what you want to do please do that outside of myFunction()!"
return 1
fi
注意,如果你需要检查很多变量,这也可以放在函数本身中。 如果我仍然想使用相同的名称(这里:returnVariable),我只是创建了一个缓冲变量,给myFunction,然后复制值returnVariable。
就是这样:
myFunction ():
myFunction() {
if [[ "${1}" = "returnVariable" ]]; then
echo "Cannot give the ouput to \"returnVariable\" as a variable with the same name is used in myFunction()!"
echo "If that is still what you want to do please do that outside of myFunction()!"
return 1
fi
if [[ "${1}" = "value" ]]; then
echo "Cannot give the ouput to \"value\" as a variable with the same name is used in myFunction()!"
echo "If that is still what you want to do please do that outside of myFunction()!"
return 1
fi
local returnVariable="${1}"
local value=$'===========\nHello World\n==========='
echo "setting the returnVariable now..."
printf -v "${returnVariable}" "%s" "${value}"
}
测试用例:
var1="I'm not greeting!"
myFunction var1
[[ $? -eq 0 ]] && echo "myFunction(): SUCCESS" || echo "myFunction(): FAILURE"
printf "var1:\n%s\n" "${var1}"
# Output:
# setting the returnVariable now...
# myFunction(): SUCCESS
# var1:
# ===========
# Hello World
# ===========
returnVariable="I'm not greeting!"
myFunction returnVariable
[[ $? -eq 0 ]] && echo "myFunction(): SUCCESS" || echo "myFunction(): FAILURE"
printf "returnVariable:\n%s\n" "${returnVariable}"
# Output
# Cannot give the ouput to "returnVariable" as a variable with the same name is used in myFunction()!
# If that is still what you want to do please do that outside of myFunction()!
# myFunction(): FAILURE
# returnVariable:
# I'm not greeting!
var2="I'm not greeting!"
myFunction "date && var2"
[[ $? -eq 0 ]] && echo "myFunction(): SUCCESS" || echo "myFunction(): FAILURE"
printf "var2:\n%s\n" "${var2}"
# Output
# setting the returnVariable now...
# ...myFunction: line ..: printf: `date && var2': not a valid identifier
# myFunction(): FAILURE
# var2:
# I'm not greeting!
myFunction var3
[[ $? -eq 0 ]] && echo "myFunction(): SUCCESS" || echo "myFunction(): FAILURE"
printf "var3:\n%s\n" "${var3}"
# Output
# setting the returnVariable now...
# myFunction(): SUCCESS
# var3:
# ===========
# Hello World
# ===========
您可以回显字符串,但通过将函数(|)连接到其他函数来捕获它。
您可以使用expr来实现,不过ShellCheck报告这种用法已弃用。
#实现一个通用的函数返回堆栈:
STACK=()
push() {
STACK+=( "${1}" )
}
pop() {
export $1="${STACK[${#STACK[@]}-1]}"
unset 'STACK[${#STACK[@]}-1]';
}
#用法:
my_func() {
push "Hello world!"
push "Hello world2!"
}
my_func ; pop MESSAGE2 ; pop MESSAGE1
echo ${MESSAGE1} ${MESSAGE2}