我们都知道这个恼人的问题:
$ printf "abc" > some-file
$ cat some-file
abc$
如果它比 更复杂,它往往会弄乱提示$
,抛出当前光标位置并且看起来很丑陋。有一些解决方案(例如这里),但它们还有另一个缺点:通过 ssh 登录到速度较慢的机器时,您可能会在提示符出现之前就开始输入。通常,您的输入会被缓冲并尽快良好地显示。但是,对于链接的解决方案,输入将被丢弃。
我如何
- 始终在新行上开始提示,尤其是。如果最后一个命令的输出没有以新行结束和
- 保留在命令行缓冲区中执行上一个命令期间已输入的未使用的输入?
答案1
这个解决方案稍微结合了问题的解决方案与一个小 Perl 片段:
以下代码.bashrc
定义了两个新函数inject
和clear_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 将立即打印它。