网络上有很多关于此问题的问题,但我发现有两个共同点之一:
- 他们给出了手动解决方案,仅打印当前正在运行的程序(不带参数)
- 使用 zsh preexec 功能(尽管我不确定它如何与屏幕交互)。我正在寻找 Bash 解决方案。
如何让屏幕标题显示整个命令运行,例如,如果我运行 3 个长时间运行的 Python 脚本,我也可以在标题中看到脚本名称?为了奖励积分,如果我能让它继续显示最后运行的命令那就更好了。
我当前的设置:
- 出口
PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"'
PS1
以。。结束>
shelltitle ">|bash"
我试过:
\033k
在and之间添加内容\033
- 与${BASH_COMMAND}
- 使用陷阱调试设置外部附加标题,因为对于没有屏幕的 XTERM,我知道解决方案。这与
PS1
.
以及上述内容的变体。我想要一个通过屏幕的解决方案,因此窗口标题和屏幕窗口列表都显示完整的命令。
作为奖励,如果 Screen 与 Vim 能够很好地交互,我真的很喜欢它,因此可以更改缓冲区/打开新文件/等等。将在屏幕标题中动态更新。
答案1
一年后,这是我使用陷阱的解决方案。这将显示主机名、当前信息PWD
和命令(如果在屏幕上,还显示屏幕内容)。这可以在set_screen_window
下面轻松定制。所有东西都应该放在你的.bashrc
.
首先使用一些辅助函数来检查我是否打开screen
:
export PROMPT_COMMAND=''
if [[ "$TERM" == "screen"* ]]; then
screen_title_slicer() { echo "${1:0:40}"; } # Arbitrary cut off. use echo $1 for full.
screen_title_format='\ek%s\e\\'
else
screen_title_slicer() { echo "${1//[^[:print:]]/}"; }
screen_title_format='\033]0;%s\007'
fi
构建命令的核心依赖于有用的BASH_COMMAND
.我做了一些自定义的事情fg
(例如显示原始命令)和cd
(获取真实的目录):
ready="Ready!"
set_screen_window() {
title_string=$1
[ -z "$title_string" ] && title_string=$(screen_title_slicer "$BASH_COMMAND")
[ "$title_string" = "fg" ] && read -ra job < <( jobs %% 2> /dev/null )
[ "$title_string" = "fg " ] && read -ra job < <(jobs "${title_string:3} 2> /dev/null")
if [ ${#job[@]} -gt 0 ]; then
title_string=$(screen_title_slicer "${job[2]}")
fi
cwd=$PWD
if [ "${title_string::3}" = "cd " ]; then
cwd=$( eval cd "$(awk '{print $2}' <<< "$BASH_COMMAND")" &> /dev/null && pwd)
[ -z "$cwd" ] && cwd=$PWD
title_string="$ready"
fi
[ "$title_string" = "cd" ] && title_string=$ready && cwd=$HOME
printf "$screen_title_format" "$HOSTNAME -- ${cwd//$HOME/\~}> $title_string" > "$(tty)"
unset job
unset title_string
}
现在用我的字符串初始化终端头ready
,并捕获错误和调试以更新终端窗口:
set_screen_window "$ready"
trap "set_screen_window $ready" ERR
trap set_screen_window DEBUG
最后,.vimrc
我们有vim
具体的内容:
function! Filename()
if @% == ""
return "noname"
endif
let is_tracked=system("git ls-files " . expand("%"))
if is_tracked == ""
return expand("%:t")
endif
return gitbranch#name() . "/" . expand("%:t")
endfunction
let &titlestring = hostname() . " -- vim " . Filename()
if &term[:5] == "screen"
set t_ts=^[k
set t_fs=^[\
set title
endif
autocmd TabEnter,WinEnter,BufReadPost,FileReadPost,BufNewFile * silent execute '!printf "\033]0;'.hostname().' -- vim '.Filename().'\007"'
autocmd TabEnter,WinEnter,BufReadPost,FileReadPost,BufNewFile * let &titlestring = hostname() . ' -- vim ' . Filename()
在这里Filename
可以定制以获得您自己的标题风格。autocmd
确保在缓冲区、窗口等之间移动时重新加载内容。gitbranch
在我的示例中,有一个插件可用于git
在编辑存储库中的文件时生成(如您所期望的)分支名称。
答案2
与PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"'
in一起使用对我来说效果很好。使用这个特定的东西会以某种方式破坏我的 PS1,所以我还添加了以下内容:.bashrc
shelltitle '$ |bash'
.screenrc
PROMPT_COMMAND
.bashrc
case "$TERM" in
screen*) PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"';;
esac
附加示例图像 - 在窗口 0 中运行 sleep,在窗口 1 中运行 find,在窗口 2 中运行 watch,在窗口 3 中运行 ping,在窗口 4 中运行 bash。