将terminal光标返回到包装启用的行首

我正在写一个filter(在一个terminal输出的pipe道中),有时候需要“覆盖”刚刚发生的一行。 它的工作原理是将stdin传递给标准的字符,直到达到\n ,然后调用特殊的行为。 我的问题是如何回到行的开始。

我想到的第一件事是使用\r或ANSI序列\033[1G 。 但是,如果线条足够长,以便在terminal上进行包装(从而使其滚动),则这些只会将光标移回当前物理线路。

我的第二个想法是跟踪行的长度(从前\n )以来传递的字符数,然后多次echo \b 。 但是,如果行包含控制字符或转义序列(可能还有Unicode?),则会出错。

search所有特殊的序列,并用它来调整我的字符数,是否有一个简单的方法来实现呢?

Solutions Collecting From Web of "将terminal光标返回到包装启用的行首"

即使有一个“魔术序列”,当写入到控制台将可靠地擦除最后写的线,你仍然会得到输出线和序列(虽然隐藏在控制台上)。 想想如果有人把输出写到一个文件中,或者把它传递给其他过滤器,会发生什么? 他们会知道如何处理这种投入吗? 不要告诉我,你排除了写在别的地方而不是直接写到控制台的可能性。 迟早,有人会想重定向输出 – 甚至可能是你!

正确的做法是在处理内存时将每行缓存,然后决定是否输出。 这真的没有办法。

您可以使用简单的ioctl查询终端维度:

 #include <sys/types.h> #include <sys/ioctl.h> // ... struct winsize ws; ioctl(1, TIOCGWINSZ, &ws); // ws.ws_col, ws.ws_row should now contain terminal dimensions 

这样,您可以防止打印超出行尾的东西,只需使用\r方法即可。

 $ cat> test.sh <<'EOF'
 >#!/ bin / sh
 >输入sc
 > echo'这是一个非常长的多行字符串:..................................... .................................................. ......”
 > tput rc
 >回声'我回去了,重写了一些东西!!!!'
 >回声
 > EOF
 $ sh test.sh
我回去重写了一些东西!  .......................................
 .................................................. ....

terminfo数据库中查找save_cursorrestore_cursor字符串功能。