微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何读取Shell脚本中的函数返回的值?

如何解决如何读取Shell脚本中的函数返回的值?

我编写了一个shell脚本,将数组作为函数的参数传递,并选择该数组的一个元素,然后将其返回给调用者。除非我将函数调用的返回值分配给变量,否则脚本将正常工作。

#!/bin/bash

operations=(Sleep Eat Play Study)
services=(Cook Clean Draw)

readOption(){
  _arr=("$@")
  #echo "${_arr[@]}"
  #echo "Value of #1 is $@"

  MAX_TRIES="5";
  COUNT="0";

  while [[ -z "$opt" && "$COUNT" -lt "$MAX_TRIES" ]]
  do
    if [ "$COUNT" != "0" ]
    then
       echo "WARN: Retries left [$((MAX_TRIES-COUNT))]. Choose the correct option."
    fi

    for i in "${!_arr[@]}";
    do
      echo $((i+1)). "${_arr[$i]}"
    done
    read -rp "Choose an option>" index;
    COUNT="$((COUNT+1))"
    opt="${_arr[$((index-1))]}"
  done
  
  if [ "$COUNT" -eq "$MAX_TRIES" ]
  then
    echo "ERROR: Exceeded maximum number of retries: $MAX_TRIES";
    echo "Exiting......";
    exit 1;
  fi
  value="${opt,}"   # Lower casing the chosen option
  unset opt
  echo "${value}"
}

opr=$( readOption "${operations[@]}" )  # It works fine if I remove the assignment
svc=$( readOption "${services[@]}" )    # It works fine if I remove the assignment

echo "Operation is: $opr"
echo "Service is: $svc"

脚本无法按预期运行的分配有什么问题?谢谢

Updated-1:

预期输出

我想显示所有数组元素。 允许用户从数组中选择一个选项。 将在函数中选择的选项返回到主脚本中的变量。

Update-2:

根据接受的答案中的建议更新了脚本。

解决方法

$(...)获取有关内部内容的标准输出。所以:

readOption() {
    read -p "This is printed on stdout!" ...
    echo "this is also printed on stdout"
    echo "${value}"      # and this is too!
}
opt=$(readOption)  # takes **ALL** stdout messages and assigns them to opt

我相信对于您来说,当前的方法最好是解决所有引用错误并用http://shellcheck.net检查脚本,并按名称传递变量名称并使用名称引用来模仿read

readOption() {
    local opt value _arr COUNT MAX_TRIES  # do not pollute global space
    declare -n _readoption_var=$1 # namereference - use unique name to avoid nameclashes
    shift
    _arr=("$@") # properly quote varibale expansions
    ... etc. etc. your code ...
    _readoption_var="$value"
}
readOption opr "${operations[@]}"

或者,您可以手动选择消息并将输出写入控制台,而不是写入标准输出:

readOption() {
    read -p "Print to console" var >&3 
    echo "print this to console too" >&3
    echo "$value" # but print this to stdout
} 

exec 3>&1 # duplicate/"clone" stdout on 3rd file descirptor
opt=$(readOption)  # stdout will go to opt
                   # but fd3 will go to terminal
# or:
opt=$(readOption) 3>&1

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。