所以,我正在尝试记录我的 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 应该检测其标准输出是否未连接到终端,并且在这种情况下不应该发出颜色代码。