screen中自动修改窗口标题,一般配置方案使用ANSI转义序列(或配合shelltitle),但是看了网上搜到的配置不太满意,尤其对于fg
命令恢复进程到前台的情况。这里给出一个比较简单的配置,支持fg
将进程恢复到前台执行后正确设置screen窗口标题。同时这个配置也便于灵活自定义修改特定命令的窗口标题设置。
简单方式
screen窗口标题设置的细节可以参考man screen
中”TITLES”章节,这里关注设置窗口标题的ANSI转义序列<esc>kNAME<esc>\
,这个转义序列可以由应用程序输出,将窗口标题设置为NAME。
对于shell,还有一种启发式的方法。将窗口标题设置为"search|name"
(一般在.screenrc中使用shelltitle指令),并在shell提示符中输出一个空名字的转义序列(也就是<esc>k<esc>\
),shell提示符末尾要与前面的search部分相同。这样screen会在接收到空名字转义序列时清空窗口标题并准备接收下一个指令,换行时会使用前面提到的search搜索提示符末尾,当这个末尾被找到,会使用之后的第一个单词作为命令名设置给窗口标题。如果这个命令名字以'!'
,'%'
,'^'
开头,会有额外的处理。
比如当shell提示符末尾为"$ "
时,使用如下设置:
- shelltitle设置为
"$ |bash"
- 配置环境变量
PROMPT_COMMAND='printf "\033k\033\134"'
像开头提到的,单纯这种方式,对于fg
恢复到前台的进程只会将窗口标题设置为fg。因此这里给出另一种配置方式,不依赖shelltitle的"search|name"
,只是使用bash的trap
和环境变量PROMPT_COMMAND
。
改进方式
下面这段配置需要添加到~/.bashrc
中或由其加载,因为screen默认创建的和C-a c
创建的窗口是交互式非登录shell,只会加载~/.bashrc
文件,不会加载~/.bash_profile
和~/.profile
,可以参考bash 调用方式与配置文件。
~/.bashrc1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| if [ -n "$STY" ]; then __get_fg_cmd() { local job_id if [[ "$*" =~ ([0-9]+) ]]; then job_id="${BASH_REMATCH[1]}" else job_id="%+" fi jobs "$job_id" 2>/dev/null | awk '{$1=$2=""; sub(/^ */, ""); print}' }
__get_vim_cmd() { local input="$*" if [[ $input =~ [[:space:]]+([^-][^[:space:]]*) ]]; then local name="${BASH_REMATCH[1]}" name=$(basename "$name") printf '[vim]%s' "$name" else printf "vim" fi } __get_cmd() { local i local _command local _sudo=0 local _extract=1 _command="$BASH_COMMAND" for i in {0..4}; do _command="${_command#"${_command%%[![:space:]]*}"}" case "$_command" in "printf "*) return ;; "fg"|"fg "*) _command=$(__get_fg_cmd $_command) ;; "vim"|"vim "*) _command=$(__get_vim_cmd $_command) # vim不继续处理 _extract=0 break ;; "sudo "*) # sudo 删除 _command=$(printf '%s' "$_command" | awk '{$1=""; sub(/^ /, ""); print}') _sudo=1 ;; *) # 跳出循环 break ;; esac done # 循环结束提取命令名 if [ $_extract -eq 1 ];then _command=$(printf '%s' "$_command" | awk '{print $1}' | sed 's#^.*/##') fi # sudo标记 if [ $_sudo -ne 0 ];then printf '#%s' "$_command" else printf '%s' "$_command" fi }
# 设置标题函数 __set_screen_title() { local cmd=$(__get_cmd) if [ x${cmd} != x ];then printf "\033k${cmd}\033\134" fi }
# 设置触发器 trap '__set_screen_title' DEBUG # 一些发行版会使用PROMPT_COMMAND改变终端窗口标题,保留原ANSI转义序列。增加返回screen默认标题bash __prompt="printf '\033kbash\033\134'" if [[ -z "$PROMPT_COMMAND" ]];then PROMPT_COMMAND="$__prompt" elif [[ "$PROMPT_COMMAND" != *"$__prompt"* ]];then PROMPT_COMMAND="$PROMPT_COMMAND;$__prompt" fi fi
|
PS:.screenrc中主要也就是配置一下term和hardstatus,左边窗口列表,右边显示时间,方便对照日志中时间、主机时间、办公电脑时间,可有可无吧。
~/.screenrc1 2 3 4 5
| term xterm
hardstatus alwayslastline hardstatus string "%-w%{= BW}%50>%n %t%{-}%+w%< %=%c %Y-%M-%d [%H]"
|