如何在解析命令的同时显示命令的输出?

如何在解析命令的同时显示命令的输出?

我有两个命令,build并且deploy.目前,我build手动运行,用自己的眼睛解析其输出,并使用我在输出中找到的值作为 的参数deploy。该过程看起来像:

$ build
==> amazon-ebs: amazon-ebs output will be in this color.
... hundreds of lines of output ...
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
us-east-1: ami-19601070

$ deploy ami-19601070
... some more output ...

build实际上是包装机,对于精明的人来说)

我想将这两个步骤结合在一个脚本中。粗略的轮廓将包括以下内容:

  • 跑步build
  • 确保退出状态为0且输出包含字符串“AMIs were Created”,否则中止
  • ami-19601070从输出中提取 AMI 编号 ( )
  • 跑步deploy ami-19601070

我正在尝试想出将所有内容连接在一起的最佳方法,最好是使用 shell 脚本,但我坚持如何 grep 两个单独模式的输出,同时理想情况下仍将所有 stdout/stderr 消息流式传输到命令运行时的终端。我想知道是否应该放弃在 shell 脚本中执行此操作的想法,而是编写一个小的 Python 脚本来执行此操作。

答案1

听起来像是一份工作tee:

build | tee /some/file
ami_name=$(do_something_to /some/file)
deploy "$ami_name"

答案2

 deployArgs=`build | tee /dev/tty  | extractDeployArgs` &&
    deploy "$deployArgs" #won't run unless extractDeployArgs suceeded

tee /dev/tty将直接打印到终端并同时将输出传递到管道中的下一个命令。

(随意将其替换为其他文件(或者/dev/fd/"$someFileDescriptor"如果您需要将侧面输出转到$someFileDescriptor))

在更高级的 shell(kshbashzsh,但不是在dash)中,您可以set -o pipefail确保管道在其任何链接失败时失败(如果extractDeployArgs无法从其输入判断是否build成功,则很有用)。

答案3

tf=$(mktemp)
build | tee "$tf"
grep -Fq 'AMIs were created' "$tf" && ami=$(grep -o 'ami-[0-9]\+$' "$tf")

# you didn't say if `deploy` can handle multiple args or not.
# uncomment one of the following:
# deploy $ami
# for a in $ami ; do deploy "$a" ; done

答案4

如果您对特定的输出字符串感兴趣,您可以像这样运行它:

msg="$(build | grep -e "AMIs were created\|ami-[0-9]*")"

if [ -n "$(echo $msg | grep -e "AMIs were created")" ];then
    ami="$(echo "$msg" | grep -e "ami-[0-9]*" | cut -d ' ' -f 2)"
    deploy "$ami"
else
    exit 1
fi

第一个 grep 仅选择输出中报告 AMI 已创建或 ami-# 的行。检查输出中是否有“AMI 已创建”,如果存在,则从相关输出中解析 ami-# 并使用它进行部署。

相关内容