链接命令的问题

链接命令的问题

所以,我正在尝试记录我的 ethminer 哈希率,但是我在将 egrep / grep 的输出链接到另一个时遇到了一些麻烦,我甚至尝试了不同的命令(sed/cat...),似乎都没有得到任何输出,我甚至无法将 stdout 重定向到文件!奇怪的是;当我不尝试链接或重定向任何东西时,它会在终端上打印它应该打印的内容!

经过大约 2 小时的研究,我仍然遇到相同的错误(可能是我的错误,但我真的无法弄清楚),甚至在复制了我找到​​的一些内容后,我仍然在同一个地方......

这是我想要过滤的命令:

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4

输出这个(它输出大约比每秒一行多一点,并且这需要基本上永远运行):

  ℹ  23:36:26|CUDA0     set work; seed: #4be89018, target:  #0000000112e0
  ℹ  23:36:26|CUDA0     set work; seed: #4be89018, target:  #0000000112e0
  m  23:36:28|ethminer  Speed  20.01 Mh/s    gpu/0 20.01  [A0+0:R0+0:F0] Time: 00:00
  m  23:36:30|ethminer  Speed  22.13 Mh/s    gpu/0 22.13  [A0+0:R0+0:F0] Time: 00:00

让我感兴趣的是《生死边缘》之后的部分,虽然有隐藏人物,但这是一个被锁链束缚的

  cat -e 

显示:

^[[32m  m  ^[[35m23:38:10^[[0m^[[30m|^[[34methminer^[[0m  Speed ^[[1;36m 23.09^[[0m Mh/s    gpu/0 ^[[36m23.09^[[0m  [A0+0:R0+0:F0] Time: 00:00^[[0m$

注意“速度 ^[[1;36m 23.09”,我使用“m”作为参考来查找表达式中的哈希率m [[:digit:]]+\.[[:digit:]]{2} (顺便说一句,您会看到我需要将 stderr 重定向到 stdout,这是因为 ethminer 似乎在 stderr 通道中输出哈希率......有点奇怪......)这给了我:

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | cat -e | egrep -o --color=never "m [[:digit:]]+\.[[:digit:]]{2}" | egrep -o [[:digit:]]+\.[[:digit:]]{2}$

这输出了它应该做的事情:

m 0.00
m 15.74
m 19.41

到目前为止,一切都很好......但是在这之后......一切都变得奇怪了......我还没有设法获得任何输出......甚至在我的终端上也没有从任何链式命令获得输出,我尝试了很多东西,从到处玩 stderr 和 stdout 的重定向,尝试了 cat:没有输出,用 sed 玩了一会儿:没有运气,用 grep:没有比 sed 更多的机会......理想情况下,我想要这样的东西:

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | cat -e | egrep -o --color=never "m [[:digit:]]+\.[[:digit:]]{2}" | egrep -o [[:digit:]]+\.[[:digit:]]{2}$ >> /home/USER/mining.log

输出结果如下:

22.26
22.47

在 mining.log 文件中...

帮助!

编辑:ethminer 来自这里:https://github.com/ethereum-mining/ethminer 这是版本 0.12.0

更新: egmont 的答案最终起作用了,如果我理解正确的话,这是因为通过管道发送的数据通过 ethminer 缓冲的方式... 这是我最终使用的命令:

stdbuf -oL ethminer [arguments] 2>&1 | stdbuf -oL cat -e | stdbuf -oL egrep -o "m [0-9]+\.[0-9]{2}" | stdbuf -oL egrep -o "[0-9]+\.[0-9]{2}" >> mining.log

答案1

大多数提供彩色终端输出的命令行程序都足够智能,能够识别出何时其输出不会发送到终端,并隐藏颜色代码。但似乎并非如此ethminer

您的解决方案是使用 将非打印 ANSI 代码转换为纯文本cat -e,然后对其进行解析。另一种(可能更强大的)解决方法可能是删除颜色代码 - 一种方法是使用perl 术语::ANSIColor模块例如

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | 
  perl -MTerm::ANSIColor=colorstrip -lne 'print colorstrip $_' | grep ...

然而,如果我们要这样做,我们不妨用perl代替 来grep进行匹配。有很多方法可以做到这一点 - 这里是其中一种:

  • 将行拆分为一个空格分隔的数组@F
  • 调用并colorstrip保存@F结果@a
  • 找到匹配的数组元素的索引Speed,然后查找并打印下一个元素

前任。

/home/USER/ethminer -U -S eu1.ethermine.org:4444 -O 0x*****************.********** --cuda-parallel-hash 4 2>&1 | 
  perl -MTerm::ANSIColor=colorstrip -alne '@a = colorstrip @F; print map { $a[$_+1] } grep { $a[$_] eq "Speed" } 0..$#a'

答案2

当输出写入终端时,默认行为是行缓冲,但是,当使用管道将输出定向到文件或另一个进程时,数据可能会以 4kB 或 8kB 的数据块进行缓冲。也就是说,您的 ethminer 需要打印这么多数据,才能真正将第一个数据块写出并可用于时间线中的下一个阶段。

用于stdbuf启用行缓冲模式,即使输出转到另一个进程,例如stdbuf -oL ethminer [parameters] | cat-or-grep-or-whatever

出于同样的原因,如果您有更长的管道,可能除了最后一个阶段之外的所有阶段都需要更改为行缓冲,如下所示:stdbuf -oL ethminer | stdbuf -oL cat -e | stdbuf -oL egrep pattern1 | egrep pattern2

颜色与这个故事无关,尽管正如另一个答案所指出的那样,ethminer 应该检测其标准输出是否未连接到终端,并且在这种情况下不应该发出颜色代码。

相关内容