如何将函数的结果分配给变量?

How do I assign the result of a function to a variable?

我编写了以下函数来计算数组的最大值:

MaxArray(){
aux =""
for n in "$@"
do
    [ "$n" -gt "$aux" ] && aux="$n"
done
return $aux
}

我尝试将 return 更改为 echo "$aux" 以查看它是否正确计算了该值并且有效。对于具有以下值的数组:(1, 10, 152, 0, 3),我尝试了 return 并调用了这样的函数:

value=$( MaxArray ${array[@]} )
echo "value is $value"

但是调用函数后$value为空。 如何将函数的 return 正确分配给 $value?

替换

return $aux

echo "$aux"

命令替换捕获标准输出,而不是退出状态。

顺便说一句,变量赋值不应该在等号前后有空格,赋值应该是

aux=""

在 shell 中,传递值是通过输出完成的,而不是 return 代码:

#!/bin/bash

MaxArray() {
    local n aux=""
    for n in "$@"
    do
        (( n > aux )) && aux=$n
    done
    echo "$aux"
}

value=$( MaxArray "${array[@]}" )

您没有 return 具有 return 的值用于 return 退出状态。您 return 通过将值发送到标准输出 (echo, printf...) 如果您的 bash 足够新,则更好的解决方案可以避免 sub-shell是将变量名作为函数参数传递并使用命名引用(local -n var=name):

MaxArray(){
  local -n tmp=""
  local -i n
  tmp=""
  shift 2
  for n in "$@"; do
    [ "$n" -gt "$tmp" ] && tmp="$n"
  done
}

然后:

$ unset value
$ MaxArray value 1 2 3 4 5 4 3 2 1
$ echo $value
5

请注意,如果您的值存储在索引数组中,您可以使用相同的原则来传递其名称而不是其内容:

$ MaxArray(){
  local -n tmp=""
  local -n arr=""
  local -i n
  tmp="${arr[0]}"
  for n in "${arr[@]}"; do
    [ "$n" -gt "$tmp" ] && tmp="$n"
  done
}

$ declare -a values=( 1 2 3 4 5 4 3 2 1 )
$ unset value
$ MaxArray value values
$ echo $value
5

return 值的函数有多种方法:

第一种方法是在全局变量中提供结果。此方法也适用于所有 POSIX-shell 变体:

#!/bin/sh

# Here we use the global ret variable to get the result of the function
ret=

max() {
  ret=
  shift
  for n
  do
    [ "$n" -gt "$ret" ] && ret=$n
  done
}

max 1 8 2 7 42 23 17

printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"

另一种常用方法也 POSIX-shell 友好。它涉及将结果流式传输到 stdout(打印),并在调用函数时将其捕获到变量中。这涉及到 sub-shell,因此应避免在循环中使用:

#!/bin/sh

max() {
  gtst=
  shift
  for n
  do
    [ "$n" -gt "$gtst" ] && gtst=$n
  done
  # Print the result
  printf %s "$gtst"
}

# Capture the printout of max into the ret variable
ret=$(max 1 8 2 7 42 23 17)

printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"

第三种方法涉及通过名称间接寻址变量,使用 eval:

#!/bin/sh

max() {
  # Get the name of the return variable
  ret_name=
  shift
  gtst=
  shift
  for n
  do
    [ "$n" -gt "$gtst" ] && gtst=$n
  done
  # Evaluate expression to assign returned value to provided variable name
  eval "$ret_name=$gtst"
}

# will get the result into the variable ret
max ret 1 8 2 7 42 23 17

# shellcheck disable=SC2154 # dynamically referrenced ret
printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"

最后,此方法使用 nameref 变量,这些变量仅适用于 Bash 从版本 4.2 开始:

#!/bin/bash

max() {
  # Get the name of the return variable into a nameref variable
  local -n gtst=
  local -i n
  shift
  gtst=
  shift
  for n
  do
    declare -p gtst
    [ "$n" -gt "$gtst" ] && gtst=$n
  done
}

# will get the result into the variable ret
declare -i ret
max ret 1 8 2 7 42 23 17

# shellcheck disable=SC2154 # dynamically referrenced ret
printf 'The maximum of %s is %s\n' '1 8 2 7 42 23 17' "$ret"

所有版本的输出相同:

The maximum of 1 8 2 7 42 23 17 is 42