Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash函数中的返回值_Bash_Function_Return Value - Fatal编程技术网

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语句-这样就可以使

我正在使用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(){
  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?