首页 > 解决方案 > 在输出正常滚动时使最后一个命令粘在终端窗口的顶部

问题描述

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

我怎样才能做到这一点?

标签: bashshellterminalzshoh-my-zsh

解决方案


GNU screen不能()将您请求的内容放在视图的顶部,但它可以使用包含硬状态行(窗口标题)的a将其放在底部: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 钩子函数。ZSHprecmd()在呈现您的提示之前运行。在执行命令之前,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(如果有一个分离的会话,它会尝试恢复一个分离的会话,否则它会启动一个新的会话)。上面描述了后两行。

请注意,如果您在不退出 shell(以及屏幕)的情况下关闭终端,屏幕会话将继续无头运行。当远程 SSH 会话断开连接时,这是一项功能,但在本地没有那么有用。


推荐阅读