如何始终在新行上打印提示并保留输入

如何始终在新行上打印提示并保留输入

我们都知道这个恼人的问题:

$ printf "abc" > some-file
$ cat some-file
abc$ 

如果它比 更复杂,它往往会弄乱提示$,抛出当前光标位置并且看起来很丑陋。有一些解决方案(例如这里),但它们还有另一个缺点:通过 ssh 登录到速度较慢的机器时,您可能会在提示符出现之前就开始输入。通常,您的输入会被缓冲并尽快良好地显示。但是,对于链接的解决方案,输入将被丢弃。

我如何

  • 始终在新行上开始提示,尤其是。如果最后一个命令的输出没有以新行结束
  • 保留在命令行缓冲区中执行上一个命令期间已输入的未使用的输入?

答案1

这个解决方案稍微结合了问题的解决方案与一个小 Perl 片段:

以下代码.bashrc定义了两个新函数injectclear_newline。每次需要打印提示时都会调用后者。前者从后者内部调用(有关详细信息,请参阅内联命令):

# injects the arguments into the terminal, from the second link
function inject() {
  perl -e 'ioctl(STDIN, 0x5412, $_) for split "", join " ", @ARGV' "$@"
}
# prints a newline if the cursor is not in position 1
clear_newline() {
  local curpos # local variable to hold the cursor position
  local input  # local variable to hold entered input
  stty -echo # disable echoing
inject '
' # inject a newline to terminate entered input, '\0' didn't work?
  IFS='\n' read -s input # read entered input
  echo -en '\033[6n'
  # ask the terminal driver to print the current cursor position
  IFS=';' read -d R -a curpos # read cursor position 
  stty echo # enable echoing
  (( curpos[1] > 1 )) && echo -e '\033[7m%\033[0m'
  # if cursor not in first column, print a % with inverted colours and a newline
  stty -echo # disable echoing of input to terminal again
  inject "${input}" # inject stored input
  stty echo # enable echo
}

PROMPT_COMMAND='clear_newline' # run clear_newline for every prompt

第二stty -echo/stty echo对是隐藏注入的输入所必需的;提示完成后,bash 将立即打印它。

相关内容