首页 > 解决方案 > 在 Bash 中,如何编写一个返回字符串来设置 var 的函数,并将日志也输出到 stdout?

问题描述

在 bash 中,我想编写一个可以为用户输出日志的函数,并返回一个字符串来设置一个变量(这是主要目的)。我面临的挑战是,通常一个函数必须回显其输出才能返回退出代码以外的任何内容,但这会阻止在函数中记录其他输出。

有没有办法做到这一点?我问的原因是因为其他命令可能会在函数内输出到 stderr 或 stdout,但我需要保护变量免受其输出。

这是一些不起作用的示例代码:

function retrieve_ami {
  local -r latest_ami="$1"
  local -r ami_role="$2"
  local -r ami_commit_hash="$3"
  local result=""
  if [[ "$latest_ami" == true ]]; then
    ami_filters="Name=tag:ami_role,Values=$ami_role"
    printf "\n...Query latest AMI"
  else
    ami_filters="Name=tag:ami_role,Values=$ami_role Name=tag:commit_hash,Values=$ami_commit_hash"
    printf "\n...Query AMI with commit: $ami_commit_hash"
  fi
  query=$(aws ec2 describe-images --filters $ami_filters --owners self --region $AWS_DEFAULT_REGION --query 'sort_by(Images, &CreationDate)[].ImageId' --output json | jq '.[-1]' --raw-output)
  if [[ "$query" != "null" ]]; then
    result="$query"
    printf "\nFound $ami_role result="
    printf "\n  $result\n"
  fi
  if [[ -z "$result" ]]; then
    printf "Images required for deployment are not present.  You will need to build them before continuing."
  fi
  # here we want to output the actual result #
  return $result
}
# And set the var
ami=$(retrieve_ami $latest_ami $ami_role $TF_VAR_ami_commit_hash)

标签: bashfunctionvariables

解决方案


bash 函数更像是调用的一段附加命令,它们不返回值。除此之外,return用于返回退出代码,例如return 1.

您可以将返回值设置为 0(如果找到 ami)并通过新变量传递 ami,它可以是result(它不能再是本地的了)。试试类似的东西(希望我没有搞砸,我现在无法测试它):

#!/bin/bash

function retrieve_ami() {
  local -r latest_ami="$1"
  local -r ami_role="$2"
  local -r ami_commit_hash="$3"
  unset result
  if [[ "$latest_ami" == true ]]; then
    ami_filters="Name=tag:ami_role,Values=$ami_role"
    printf "\n...Query latest AMI"
  else
    ami_filters="Name=tag:ami_role,Values=$ami_role Name=tag:commit_hash,Values=$ami_commit_hash"
    printf "\n...Query AMI with commit: $ami_commit_hash"
  fi
  query=$(aws ec2 describe-images --filters $ami_filters --owners self --region $AWS_DEFAULT_REGION --query 'sort_by(Images, &CreationDate)[].ImageId' --output json | jq '.[-1]' --raw-output)
  if [[ "$query" != "null" ]]; then
    result="$query"
    printf "\nFound $ami_role result="
    printf "\n  $result\n"
    return 0
  fi
  if [[ -z "$result" ]]; then
    printf "Images required for deployment are not present.  You will need to build them before continuing."
    return 1
  fi
}
# And set the var
if retrieve_ami $latest_ami $ami_role $TF_VAR_ami_commit_hash; then
  # function returned true / 0
  ami=${result}
else
  # function returned an error / 1
  echo "Error finding ami"
fi

请注意不要使用之前已经使用过的变量/不要在其他地方覆盖它

请仔细检查以下链接以获取更多信息:


推荐阅读