我有以下BASH函数,该函数接受参数并将其显示在终端的底部,并在新行中显示在滚动区域之外:
bottomLine() {
clear
# Get all arguments and assign them to a var
CONTENT=$@
# Save cursor position
tput sc
# Add a new line
tput il 1
# Change scroll region to exclude the last lines
tput csr 0 $(($(tput lines) - 3))
# Move cursor to bottom line
tput cup $(tput lines) 0
# Clear to the end of the line
tput el
# Echo the content on that row
echo -ne "${CONTENT}"
# Restore cursor position
tput rc
}
这非常简单并且有效。问题是,在执行了一些命令之后(有时仅需要几个命令,有时甚至需要15分钟),该行将被向上滚动,即使该行应从滚动区域中排除。
在蒂尔达和终结者中我都遇到这种情况。
任何帮助,不胜感激。
编辑:重现此问题的最佳方法是,如果执行多个“ ls -a,ls -a,ls -a,ls -a”直到到达页面底部,然后使用Vi打开一个随机文件然后再执行另一个“ ls -a”。当您执行此操作时,即使无法滚动,最底端的行也会位于上方。
答案 0 :(得分:2)
我的第一个冲动是回答说,无法永久冻结可滚动区域,因为任何操作终端的程序(如vim都可以)会覆盖您的设置。但是后来我发现可以通过shell提示功能恢复设置。为此,您必须将终端控制序列添加到PS1
环境变量中。
我已经修改了您的函数,以便它在第一次调用时自动更新提示。为此,我不得不将其分为两个功能。
bottomLineTermCtlSeq() {
#clear
# Save cursor position
tput sc
# Add a new line
tput il 1
# Change scroll region to exclude the last lines
tput csr 0 $(($(tput lines) - 3))
# Move cursor to bottom line
tput cup $(tput lines) 0
# Clear to the end of the line
tput el
# Echo the content on that row
cat "${BOTTOM_LINE_CONTENT_FILE}"
# Restore cursor position
tput rc
}
bottomLine() {
local bottomLinePromptSeq='\[$(bottomLineTermCtlSeq)\]'
if [[ "$PS1" != *$bottomLinePromptSeq* ]]
then
PS1="$bottomLinePromptSeq$PS1"
fi
if [ -z "$BOTTOM_LINE_CONTENT_FILE" ]
then
export BOTTOM_LINE_CONTENT_FILE="$(mktemp --tmpdir bottom_line.$$.XXX)"
fi
echo -ne "$@" > "$BOTTOM_LINE_CONTENT_FILE"
bottomLineTermCtlSeq
}
我将底行的当前内容存储在文件中,而不是环境变量中,以便顶层shell的子进程也可以操纵底行。
请注意,我从终端操作序列中删除了clear
命令,这意味着您可能需要在第一次调用bottomLine
之前(在您到达屏幕底部)。
还请注意,调整终端窗口的大小时可能会弄乱底线。