bash - 当传递给 sed 或 awk 时,冗长的管道命令输出挂起

标签 bash macos awk sed pipe

背景

我正在对我的 CI 构建进行更改,该构建会触发一个命令来运行我的 Xcode 单元测试输出。这些测试记录了极其冗长的信息量——太多以至于我超过了 4 MB 的日志捕获限制并且我的构建被终止。据我所知,我没有办法让它不那么冗长(我想出的一种方法是需要更改运行测试的命令,which I'm working on

我的解决方法

所以我决定变聪明,尝试使用 sed 过滤我的输出,如下所示:

test_running_command | sed '/xctest\[/d; /^$/d'

当我在文件上运行 sed 命令时,它会正常工作,按预期过滤掉包含 xctest[ 的行和空行。但是当我将它合并到我的 CI 构建中时,我​​看到输出流到某个点,然后就停止了。 10 分钟后,在我有机会达到 4 MB 限制之前,我的 CI 构建无论如何都被杀死了。

问题

为什么 sed 挂成这样?

已执行故障排除

  • 我尝试使用 awk,就像这样,它同样挂起。

    test_running_command | awk '$0 !~ /xctest\[/ && $0 !~ /^$/ {print}'
    
  • 我尝试了一个命令 from this answer为原来的命令打开行缓冲,它只是卡在不同的地方。

    script -q /dev/null test_running_command | <sed or awk command from above>
    
  • 正如@CharlesDuffy 在评论中所建议的那样,我使用 tee 将进入管道的内容写入文件,并确定管道的左侧肯定比正确的。我(在我的本地机器上)观察到,虽然控制台的输出被卡住,但 before_filter.txt 仍在继续。这是我使用的行:

    test_running_command | tee before.txt | sed '/xctest\[/d; /^$/d' | tee after.txt
    
  • 正如@LuisMuñoz 在评论中所建议的那样,我尝试使用 stdbuf(在使用 brew install coreutils 安装之后)禁用进出 sed 的缓冲。我没有看到行为上的差异。输出仍然卡住在任意点。

    test_running_command | gstdbuf -i0 -o0 sed '/xctest\[/d; /^$/d'
    

最佳答案

我发现了 sed-l 标志。显然,这打开了行缓冲模式,产生了预期的效果。我想知道它是否有问题,因为它的缓冲区被产生的令人难以置信的长行溢出了。不管怎样,这个命令最终起作用了:

 test_running_command | sed -l '/xctest\[/d; /^$/d'

附带说明一下,我有一个测试在 CI 服务器上花费的时间超过 10 分钟,并且没有日志输出,这导致了超时。我在其外层循环中放置了一个 printf 语句,它产生的日志输出刚好足够,因此构建不会被终止。 printf 行没有被 sed 命令过滤,所以这是完美的。

关于bash - 当传递给 sed 或 awk 时,冗长的管道命令输出挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49661118/

相关文章:

ruby-on-rails - Mac OSX Ruby on Rails 安装问题 - 找不到文件/生成文档时出错

shell - 使用 AWK 验证 if 循环条件中的日期格式

linux - 按文件名中的标签排序文件

c++ - boost :未知类型名称 'reference_type_of_temporary_wrapper'

ruby-on-rails - mysql2 gem 无法构建原生扩展

linux - 如何控制 AWK 更改哪些输出字段分隔符,哪些不更改

包含反引号的 Linux 管道数据

bash - 管道命令链,每个命令输出状态为标准错误

linux - Bash 脚本监控日志,匹配关键字然后发送命令,恢复监控

linux - 如何在 bash 中转换文本文件? (foo.txt 到 bar.txt)