在输出正常滚动时,使最后一个命令停留在终端窗口的顶部

时间:2019-05-13 22:42:48

标签: bash shell terminal zsh oh-my-zsh

我想打印正在运行的命令以及始终在哪个目录中作为窗口的顶行,即使该命令的输出通常会导致其滚动。我希望普通输出显示在下方并正常滚动。

我该怎么做?

4 个答案:

答案 0 :(得分:1)

我想到的第一个方法是将命令放在终端仿真器的标题中。
它会出现在窗口标题或选项卡名称中。
您可能需要调整设置才能显示它。

~/.zshrc中添加或编辑此功能

preexec() {
   print -Pn "\e]0;$1\a"
}

答案 1 :(得分:1)

我不知道如何在终端会话中实现这一目标,但是可以为命令编写函数。

#! /bin/bash

function _sticky_cmd {
        local cmd=$@
        X=1
        L=$(tput lines)
        ((L=L-1))
        LINES=()
        eval $cmd | while IFS= read -r line; do
                pos=$((X-L))
                [ $pos -ge 0 ] || pos=0
                LINES+=("\n$line")
                echo -en "\033c$cmd : $(pwd)"
                echo -en "${LINES[@]:$pos:$L}" | sed -r 's/^ //g'
                ((X=X+1))
        done
}

_sticky_cmd 'while true; do echo "test $((n=n+1))"; sleep 0.5; done'

这将产生:

while true; do echo test $((n=n+1)); sleep 0.5; done: /home/user/test/scroll
test 1 
test 2 
test 3 
test 4 
test 5 

答案 2 :(得分:1)

GNU screen无法(yet)将请求的内容放在视图的顶部中,但可以将其放置在底部 >使用包含硬状态行(窗口标题)的caption

% print 'caption always "%h"\nterm $TERM' > ~/.screenrc
% screen
% precmd() { print -Pn "\e]0;[%~] "; print -Rn "$1"; print -Pn "\e\\"; }
% preexec() { precmd "$1"; }

请注意:第一行会覆盖您的~/.screenrc,您可能不想这样做。

这将在终端的底部为您提供一条颜色反转的状态行,其中该路径包含在方括号中,然后是当前运行的命令(如果有)。例如,使用cd /tmp; sleep 1在主目录中尝试。它将显示[~] cd /tmp; sleep 1一秒钟,然后将其更改为[/tmp]

precmd()preexec()zsh hook functions。 ZSH在呈现提示之前立即运行precmd()。在执行命令之前,zsh在将preexec()设置为整个命令的情况下运行$1。 (使用$2遍历别名。)

以上precmd()进行了三个print调用,以确保从命令行限制转义码(-R禁止转义序列插值,-P启用路径变量扩展,并且-n禁止尾随换行符)。 \e]0;是开始状态行的几种方法之一,而\e\\是结束状态行的几种方法之一。上面的preexec()将命令传递到precmd()

保存了~/.screenrc后,您可以将以下内容放入~/.zshrc中,以确保始终如此:

if [ -z "$STY" ]; then screen -r 2>/dev/null || screen; fi
precmd() { print -Pn "\e]0;[%~] "; print -Rn "$1"; print -Pn "\e\\"; }
preexec() { precmd "$1"; }

如果您尚未进入这样的会话,则第一行将启动screen(如果有一个会话,它将尝试恢复一个分离的会话,否则它将启动一个新的会话)。以上是后两行。

请注意,如果在不退出外壳的情况下关闭端子(因此也没有退出屏幕),则屏幕会话将继续无提示运行。当涉及到断开连接的远程SSH会话时,这是一项功能,但在本地没有那么有用。

答案 3 :(得分:0)

以下内容适用于gnome-terminal(xterm-256color)中的bash。

例如,将以下脚本另存为$ HOME / usl(“更新状态行”的缩写)。 然后启动一个新终端,并在该终端中发出以下命令:

PROMPT_COMMAND="source $HOME/usl"

您现在有一个状态行。 脚本:

#!/bin/bash

# works with:
# gnome-terminal, using VTE version 0.42.5 +GNUTLS
# plus:
# GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

COLOR_BLUE="\e[1;44;37m"
COLOR_NONE="\e[m"

lines=$(tput lines)     # get the number of lines on the terminal

this_cmd=":"

update_status_line()
{
    prev_cmd="$this_cmd"
    this_cmd="`echo "$*" | head -n1`"

    # filter out ourselves
    [ "$this_cmd" == "$PROMPT_COMMAND" ] && this_cmd=":"    # or choose something different from ':'

    tput sc                 # save cursor position
    tput cup 0 0            # move cursor to row #1 columns #2 (0-based)
    tput el                 # clear from the current position to the end of the line, leaving the cursor where it is

    echo -ne "${COLOR_BLUE}[${prev_cmd}]\t\t${this_cmd}${COLOR_NONE}"

    tput csr 1 "$lines"     # set scroll region to 1-$lines (0-based)
    tput rc                 # restore cursor position

    LINES="$lines"
    stty rows "$lines"
    export LINES
}

# the DEBUG signal is delivered just before the command line is executed by bash;
# that's the moment of opportunity for us
trap 'update_status_line $BASH_COMMAND' DEBUG