如何限制可能过于冗长的命令的输出?

时间:2017-04-24 18:38:01

标签: bash stdout

我正在寻找一个bash片段来限制shell命令的控制台输出量,这可能会变得过于冗长。

这样做的目的是在构建/ CI环境中使用,在这种环境中,您确实希望限制控制台输出的数量,以防止CI服务器过载(甚至客户端拖尾输出)。

完整要求:

  • 仅显示命令输出顶部(头部)最多100行
  • 仅显示命令输出底部(尾部)最多100行
  • stdoutstderr完整归档到command.log.gz文件中
  • 控制台输出必须相对实时显示,最终输出结果的解决方案是不可接受的,因为我们需要能够看到它的执行进度。

目前的调查结果

  • unbuffer可用于强制stdout / stderr无缓冲
  • |& tee可用于将输出发送到archiver和tail / head
  • |& gzip --stdout >command.log.gz可归档控制台输出
  • head -n100tail -n100可用于限制控制台输出,如果输出行数少于200,则至少会出现一些问题,如不良结果。

3 个答案:

答案 0 :(得分:1)

根据我的理解,您需要在线限制输出(在生成时)。 这是我能想到的一个对你有用的功能。

limit_output() {
    FullLogFile="./output.log"  # Log file to keep the input content
    typeset -i MAX=15   # number or lines from head, from tail
    typeset -i LINES=0  # number of lines displayed

    # tee will save the copy of the input into a log file
    tee "$FullLogFile" | {
        # The pipe will cause this part to be executed in a subshell
        # The command keeps LINES from losing it's value before if
        while read -r Line; do
            if [[ $LINES -lt $MAX ]]; then
                LINES=LINES+1
                echo "$Line"    # Display first few lines on screen
            elif [[ $LINES -lt $(($MAX*2)) ]]; then
                LINES=LINES+1   # Count the lines for a little longer
                echo -n "."     # Reduce line output to single dot
            else
                echo -n "."     # Reduce line output to single dot
            fi
        done
        echo ""     # Finish with the dots
        # Tail last few lines, not found in head and not more then max
        if [[ $LINES -gt $MAX ]]; then
            tail -n $(($LINES-$MAX)) "$FullLogFile"
        fi
    }
}

在脚本中使用它,将其加载到当前shell或将其放入.bash_profile以加载到用户会话中。

使用示例:cat /var/log/messages | limit_output./configure | limit_output

该函数将读取标准输入,将其保存到日志文件,显示第一个MAX行,然后将每行减少到屏幕上的单个点(。),最后显示最后的MAX行(如果输出则更少)比MAX * 2短。

答案 1 :(得分:0)

这是我当前的不完整解决方案,为方便起见,该解决方案展示处理10行输出,并且(希望)将输出限制为前2行和后2行。

#!/bin/bash

seq 10 | tee >(gzip --stdout >output.log.gz) | tail -n2

答案 2 :(得分:0)

实现这一目标的一种方法是:

./configure | tee output.log | head -n 5; tail -n 2 output.log

这是什么?

  1. 使用output.log将完整的输出写入名为tee的文件中
  2. 仅使用head -n打印出前5行
  3. 最后,使用output.log打印书面tail -n的最后两行