启用--no-wrap参数时watch命令为何跳过隔行?(行内容均较短)
为何
watch --no-wrap会出现隔行跳过的异常现象? 问题场景
执行以下命令:
watch --no-wrap 'echo 0\n1\n2\n3\n4\n5\n6\n7\n8\n9'
得到异常输出,仅显示偶数行内容:
Every 2.0s: echo 0\n1\n2\n3\n4\n5\n6\n7\n8\n9 dave: Thu Apr 18 18:06:55 2024 0 2 4 6 8
根据watch --help的说明,--no-wrap参数仅用于关闭行换行功能:
-w, --no-wrap turn off line wrapping
而本次输出的每行内容极短,完全不存在换行需求,却出现了隔行丢失的异常。
对比不加--no-wrap参数的正常输出,所有行均能正常显示:
Every 2.0s: echo 0\n1\n2\n3\n4\n5\n6\n7\n8\n9 dave: Thu Apr 18 18:10:32 2024 0 1 2 3 4 5 6 7 8 9
相关环境信息:
% watch --version watch from procps-ng 3.3.17 % echo $LINES $COLUMNS 45 143
原因解析
这是procps-ng 3.3.17版本中watch命令的已知bug。当启用--no-wrap参数时,程序内部处理输出行的逻辑存在错误:它会错误地将连续两行合并,之后仅保留合并结果的第一部分,导致奇数行(1、3、5...)被丢弃,最终只显示偶数行内容。
具体来说,watch在--no-wrap模式下原本是要截断过长的行以适配终端宽度,但针对短行的处理逻辑出现了漏洞,最终引发了隔行丢失的问题。该bug已在procps-ng 3.3.18及后续版本中被修复。
临时解决方法
- 升级procps-ng到最新版本,彻底修复该bug;
- 若无法升级,可暂时不使用
--no-wrap参数(本次场景下输出行无需关闭换行); - 或者通过管道绕过
watch的错误处理逻辑,例如:watch 'echo -e "0\n1\n2\n3\n4\n5\n6\n7\n8\n9" | cat'
内容的提问来源于stack exchange,提问作者Dave Butler
相关产品推荐
相关产品推荐

