清除bash中的旧提示行以节省滚动空间


11

我的终端主题曾经是这样,

终端他们之前

但是我认为提示浪费了很多空间。后来我有了一个主意,每次运行命令时都可以清除提示。我正在使用bash,解决方案之一是使用该preexec_invoke_exec功能。

我使用以下命令清除最后一个提示字符:

echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"

这样终端很干净

在此处输入图片说明

但是现在我的问题是,如果我想在一行中使用多个命令(例如,当我使用)时会出现问题for i in ...

这是我的.bashrc中函数的完整版本,

preexec () { echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"; echo -n "$1"; echo -ne "  \033[37;2m["; echo -n "$2"; echo -ne "]\033[0m\n"; }
preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`; 
    preexec "$this_command" "$this_pwd"
}
trap 'preexec_invoke_exec' DEBUG

Glyph Lefkowitz zsh技巧 -太好了!

2
简单的解决方案开始于zsh……
吉尔斯(Gills'SO-别再邪恶了)

我想念你在那里的问题了……
David Hoelzer 2014年

@DavidHoelzer好吧,如果您for i in $(seq 1 10); do ls; done使用他的功能,那么可以说迭代命令的输出被“吞噬”了。因此,OP希望在启用该提示时清理该行为。我之所以支持这一点,是因为对shell的意识,可用性,反馈和可移植性感兴趣。我在先前的评论中添加的链接导致了有关超级用户的文章-他们陷入了归因于此代码段的麻烦,因此这是一个以trap函数形式模拟本机zsh功能(我认为很有趣)的原型。这里。

Answers:


3

首先preexec_invoke_exec必须进行修改,以防止多次执行preexec。另外,请修改preexec以考虑到实际的行数$PS1

preexec () { 
    # delete old prompt; one "\e[1A\e[K" per line of $PS1
    for (( i=0, l=$(echo -e $PS1 | wc -l) ; i < l ; i++ ))
    do             
        echo -ne "\e[1A\e[K"
    done
    # replacement for prompt
    echo -ne "\e[31;1m$ \e[0m"
    echo -n "$1"
    echo -ne "  \e[37;2m["
    echo -n "$2"
    echo -e "]\e[0m"
}

preexec_invoke_exec () {
    [ -n "$DONTCLEANPROMPT" ] && return
    DONTCLEANPROMPT=x
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`
    preexec "$this_command" "$this_pwd"
}

trap 'preexec_invoke_exec' DEBUG

PROMPT_COMMAND='unset DONTCLEANPROMPT'

为了preexec再次运行,DONTCLEANPROMPT必须将其取消设置或设置为''。这是通过进行的PROMPT_COMMAND,它在发出主提示之前就运行了。因此preexec,每个命令行将仅运行一次。


您的解决方案可以解决for循环问题!谢谢!进一步的不便。发生的事情是,如果您ls在命令上执行并获得输出,然后再执行一次ls,您将看到先前输出的最后一行被删除了……您有解决该问题的想法吗?

1
您可能只使用一行提示。将第一个回显更改prexec为print "\033[1A\033[K\033[31;1m$ \033[0m",即只有一个\033[1A\033[K(向上移动1行,删除至行尾),而不是两个。
阿达芬2014年

完美无瑕!非常感谢您的解决方案,并花时间解释。这解决了OP的问题,并进一步调试了解决方案。使它对所有人都可用!干杯!
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.