首页 > 解决方案 > bash 将块代码输出重定向到函数中

问题描述

我有一个简单的问题,但并没有真正找到答案,因为大多数时候他们重定向到文件日志而不是函数:/

我只是希望将所有 STDIN 和 STDOUT 重定向到一个将所有内容插入云手表的函数中。

function insert_logs_into_cloud_watch {
  errorMessage=$1
  echo ${errorMessage}
}

{
  // block of lot of code
} 2>&1 | insert_logs_into_cloud_watch

在我使用插入日志文件之前

{
  // block of lot of code
} 2>&1 | tee my_log_file.log

但是我怎样才能做到这一点呢?

谢谢你们的帮助。

标签: bashstdoutstdinio-redirection

解决方案


如何做到这一点取决于您是否要将每一行输出作为单独的日志事件发送,这将是这样的:

function insert_logs_into_cloud_watch {
  while IFS= read -r errorMessage; do
    TIMESTAMP=$(command to get timestamp in appropriate format)
    aws logs put-log-events --log-group-name "$CW_GROUP_NAME" --log-stream-name "$CW_LOG_STREAM_NAME" --log-events timestamp=$TIMESTAMP,message="$errorMessage" --sequence-token $TOKEN
  done
}

{
  // block of lot of code
} 2>&1 | insert_logs_into_cloud_watch

说明:read从标准输入(从代码块通过管道传输)一次获取一行,然后您需要获取当前时间戳并将该行作为日志消息提交。

或者,如果您想将整个输出作为单个消息发送,您可以执行以下操作:

errorMessage=$(
  exec 2>&1
  // block of lot of code
)
TIMESTAMP=$(command to get timestamp in appropriate format)
aws logs put-log-events --log-group-name "$CW_GROUP_NAME" --log-stream-name "$CW_LOG_STREAM_NAME" --log-events timestamp=$TIMESTAMP,message="$errorMessage" --sequence-token $TOKEN

解释:该exec命令将标准错误合并到标准输出中;$( )捕获该输出,以便可以将其放入变量中。

顺便说一句,这里有一点警告:在两个版本中,代码块都在子shell中执行(第一个是因为管道,第二个是因为$( )),这意味着对变量或类似的任何更改都是本地的块(即当块完成时它们将丢失)。有一些方法可以避免这种情况,但它们使整个事情变得更加复杂。


推荐阅读