Bash函数中的返回值
我正在使用bash脚本,我想执行一个函数来打印返回值:Bash函数中的返回值,bash,function,return-value,Bash,Function,Return Value,我正在使用bash脚本,我想执行一个函数来打印返回值: function fun1(){ return 34 } function fun2(){ local res=$(fun1) echo $res } 当我执行fun2时,它不会打印“34”。为什么会出现这种情况?尽管Bash有一个return语句,但您唯一可以用它指定的是函数自己的exit状态(介于0和255之间的值,0表示“成功”)。所以return不是您想要的 您可能希望将return语句转换为echo语句-这样就可以使
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
当我执行
fun2
时,它不会打印“34”。为什么会出现这种情况?尽管Bash有一个return
语句,但您唯一可以用它指定的是函数自己的exit
状态(介于0
和255
之间的值,0表示“成功”)。所以return
不是您想要的
您可能希望将return
语句转换为echo
语句-这样就可以使用$()
大括号捕获函数输出,这似乎正是您想要的
以下是一个例子:
function fun1(){
echo 34
}
function fun2(){
local res=$(fun1)
echo $res
}
获取返回值的另一种方法(如果您只想返回一个整数0-255)是$?
function fun1(){
return 34
}
function fun2(){
fun1
local res=$?
echo $res
}
另外,请注意,您可以使用返回值来使用布尔逻辑,如fun1 | | fun2
仅在fun1
返回非0
值时运行fun2
。默认返回值是在函数中执行的最后一条语句的退出值。$(…)
捕获由函数中包含的命令发送到标准输出的文本<代码>返回不输出为标准输出<代码>$?包含最后一个命令的结果代码
fun1 (){
return 34
}
fun2 (){
fun1
local res=$?
echo $res
}
return
语句设置函数的退出代码,这与exit
对整个脚本的作用非常相似
最后一个命令的退出代码始终在$?
变量中可用
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $? # <-- Always echos 0 since the 'local' command passes.
res=$(fun1)
echo $? #<-- Outputs 34
}
函数fun1(){
返回34
}
函数fun2(){
本地资源=$(fun1)
Bash中的echo$?#函数与其他语言中的函数不同,它们实际上是命令。因此,函数的使用就好像它们是从路径中获取的二进制文件或脚本一样。从程序逻辑的角度来看,应该没有什么区别
Shell命令是通过管道(也称为流)连接的,而不是“real”中的基本或用户定义的数据类型编程语言。没有命令的返回值这样的东西,可能主要是因为没有真正的方法来声明它。它可能出现在手册页上,或者命令的--help
输出上,但两者都是人类可读的,因此都是随风编写的
当一个命令想要获取输入时,它会从它的输入流或参数列表中读取它。在这两种情况下,文本字符串都必须被解析
当命令想要返回某个内容时,它必须将其回显到其输出流中。另一种常用的方法是将返回值存储在专用的全局变量中。写入输出流更清晰、更灵活,因为它还可以获取二进制数据。例如,您可以轻松地返回:
正如其他人在这个线程中所写的那样,调用方还可以使用命令替换$()
来捕获输出
同时,该函数将“返回”gpg的退出代码。将退出代码视为其他语言所没有的额外功能,或者视您的性格而定,将其视为“Schmutzeffekt”shell函数的。按照惯例,此状态为成功时为0,或其他值为1-255范围内的整数。要明确说明:return
(如exit
)只能取0-255之间的值,而0以外的值不一定是错误,这是经常断言的
当您不使用return
提供显式值时,状态取自Bash语句/函数/命令中的最后一个命令,依此类推。因此始终存在状态,return
只是提供状态的一种简单方法。如果在定义函数的脚本中运行,我喜欢执行以下操作:
POINTER= # Used for function return values
my_function() {
# Do stuff
POINTER="my_function_return"
}
my_other_function() {
# Do stuff
POINTER="my_other_function_return"
}
my_function
RESULT="$POINTER"
my_other_function
RESULT="$POINTER"
我喜欢这样,因为如果需要,我可以在函数中包含echo语句
my_function() {
echo "-> my_function()"
# Do stuff
POINTER="my_function_return"
echo "<- my_function. $POINTER"
}
my_函数(){
echo“->my_函数()
#做事
指针=“我的函数返回”
Windows上的echo“正在对多个返回值使用数组
Bash代码:
#!/bin/bash
## A 6-element array used for returning
## values from functions:
declare -a RET_ARR
RET_ARR[0]="A"
RET_ARR[1]="B"
RET_ARR[2]="C"
RET_ARR[3]="D"
RET_ARR[4]="E"
RET_ARR[5]="F"
function FN_MULTIPLE_RETURN_VALUES(){
## Give the positional arguments/inputs
## $1 and $2 some sensible names:
local out_dex_1="$1" ## Output index
local out_dex_2="$2" ## Output index
## Echo for debugging:
echo "Running: FN_MULTIPLE_RETURN_VALUES"
## Here: Calculate output values:
local op_var_1="Hello"
local op_var_2="World"
## Set the return values:
RET_ARR[ $out_dex_1 ]=$op_var_1
RET_ARR[ $out_dex_2 ]=$op_var_2
}
echo "FN_MULTIPLE_RETURN_VALUES EXAMPLES:"
echo "-------------------------------------------"
fn="FN_MULTIPLE_RETURN_VALUES"
out_dex_a=0
out_dex_b=1
eval $fn $out_dex_a $out_dex_b ## <-- Call function
a=${RET_ARR[0]} && echo "RET_ARR[0]: $a "
b=${RET_ARR[1]} && echo "RET_ARR[1]: $b "
echo
## ---------------------------------------------- ##
c="2"
d="3"
FN_MULTIPLE_RETURN_VALUES $c $d ## <--Call function
c_res=${RET_ARR[2]} && echo "RET_ARR[2]: $c_res "
d_res=${RET_ARR[3]} && echo "RET_ARR[3]: $d_res "
echo
## ---------------------------------------------- ##
FN_MULTIPLE_RETURN_VALUES 4 5 ## <--- Call function
e=${RET_ARR[4]} && echo "RET_ARR[4]: $e "
f=${RET_ARR[5]} && echo "RET_ARR[5]: $f "
echo
##----------------------------------------------##
read -p "Press Enter To Exit:"
FN_MULTIPLE_RETURN_VALUES EXAMPLES:
-------------------------------------------
Running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[0]: Hello
RET_ARR[1]: World
Running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[2]: Hello
RET_ARR[3]: World
Running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[4]: Hello
RET_ARR[5]: World
Press Enter To Exit:
作为对他人优秀帖子的补充,这里有一篇文章总结了这些技巧:
- 设置一个全局变量
- 设置一个全局变量,将其名称传递给函数
- 设置返回代码(并使用$?)
- “echo”一些数据(并使用MYVAR=$(myfunction)拾取)
其他答案的问题是,它们要么使用全局设置,当调用链中有多个函数时,全局设置会被覆盖;要么使用echo
,这意味着您的函数无法输出诊断信息(您将忘记函数执行此操作和“结果”)“,即返回值,将包含比调用者预期的更多的信息,从而导致奇怪的错误),或eval
太重和粗糙
正确的方法是将顶级内容放入函数中,并使用带有Bash动态作用域规则的local
。示例:
func1()
{
ret_val=hi
}
func2()
{
ret_val=bye
}
func3()
{
local ret_val=nothing
echo $ret_val
func1
echo $ret_val
func2
echo $ret_val
}
func3
这个输出
什么都没有
你好
再见
动态作用域是指ret\u val
指向不同的对象,具体取决于调用方!这与大多数编程语言使用的词法作用域不同。实际上,这很容易被忽略,而且解释得不太清楚。以下是相关文档(重点是我的):
函数的局部变量可以用局部变量声明
内置。这些变量仅对函数和
它调用的命令
对于C++、C++、Python、java、C语言或JavaScript背景的人来说,这可能是最大的障碍:BASH中的函数不是函数,它们是命令,它们的行为是:它们可以输出到 STDUD>
/Code > STDRRR
,它们可以在管中输入/输出,并且可以返回退出代码。基本上,D之间没有任何区别。在脚本中定义命令并创建可从该命令调用的可执行文件
func1()
{
ret_val=hi
}
func2()
{
ret_val=bye
}
func3()
{
local ret_val=nothing
echo $ret_val
func1
echo $ret_val
func2
echo $ret_val
}
func3
function example {
local -n VAR=$1
VAR=foo
}
example RESULT
echo $RESULT
var1="is there"
var2="anybody"
function modify_args() {
echo "Modifying first argument"
eval $1="out"
echo "Modifying second argument"
eval $2="there?"
}
modify_args var1 var2
# Prints "Modifying first argument" and "Modifying second argument"
# Sets var1 = out
# Sets var2 = there?