5

这里的情况,我想做一些终端交互,我想启动子线程刷新前N行,并使用主线程来处理用户输入。

之后程序将打印可变字符串,也许是一些日志。

子线程是这样的:

    let mut count: i32 = 0;
    loop {
        println!("\x1B[2F\x1B[2KHi user1, count:{}\n", count);
        count += 1;
        let ten_millis = time::Duration::from_millis(1000);
        thread::sleep(ten_millis);
    }

例如:

----------------
Hi user1, count: 0


Input:  1+1
Output: 2
----------------

刷新代码运行良好,但光标将重置到行首,我想始终将其移动到最后一行的末尾。我该怎么做这个把戏?

任何帮助将不胜感激。

4

3 回答 3

6

当归结为移动光标时,您可能对简单的ANSI 转义序列感兴趣:

ANSI 转义序列允许您随意在屏幕上移动光标。这对于由 shell 脚本生成的全屏用户界面更有用,但也可以在提示中使用。运动转义序列如下:

  • 定位光标: \033[<L>;<C>H\033[<L>;<C>f 将光标置于 L 行和 C 列。
  • 将光标向上移动 N 行: \033[<N>A
  • 将光标向下移动 N 行: \033[<N>B
  • 将光标向前移动 N 列:\033[<N>C
  • 将光标向后移动 N 列: \033[<N>D
  • 清屏,移动到 (0,0): \033[2J
  • 擦除到行尾: \033[K
  • 保存光标位置: \033[s
  • 恢复光标位置: \033[u

来源:Bash Prompt HOWTO:光标移动

虽然这些 ANSI 转义序列工作得非常好,但您可能不时对使用 感兴趣,tput因为它使您的脚本更具可读性。在这里解释tput有点矫枉过正,但上面的命令可以这样完成:

  • 定位光标: tput cup <L> <C> 将光标置于 L 行和 C 列。
  • 将光标向上移动 N 行: tput cuu <N>
  • 将光标向下移动 N 行: tput cud <N>
  • 将光标向前移动 N 列: tput cuf <N>
  • 将光标向后移动 N 列: tput cub <N>
  • 清屏,移动到 (0,0): tput clear
  • 擦除到行尾: tput el
  • 保存光标位置: tput sc
  • 恢复光标位置: tput rc

有许多许多其他选项可用。看

  • man tput
  • man 5 terminfo
于 2018-12-17T17:43:39.200 回答
0

虽然没有完全回答您的问题,但执行此操作的标准bash方法是watch

例如:

watch df -h

于 2018-12-20T14:14:44.270 回答
0

您可以让孩子“知道”输入正在进行中,在这种情况下,请遵循println!

  • 带有额外的向下光标(即\x1B[B)或下一行(\x1B[E),
  • 然后使用提示的长度加上当前输入的长度在该行中移动,例如,光标向前(即,\x1B[C列数作为参数之前的参数C)。

就像是

if (input_length) {
    cursor_down();
    cursor_forward(prompt_length + input_length);
}
于 2018-12-14T10:21:39.723 回答