Entries Tagged as 'bash-prompt-xterm'

关于linux下bash的环境变量PROMPT_COMMAND

问题提出

作为系统管理员
经常需要在模拟终端上远程登上服务器做各种操作
而且很多时候需要同时用不同的窗口登上不同的服务器
当登上服务器太多的时候
就偶然会发现突然不知道哪个窗口登的是哪台服务器了
这可是个大问题
如果在错误的服务器里执行了特定命令
有时候后果是非常严重的
因而就想能否有种办法能让人一目了然的分辨出哪个窗口登陆的是哪台机器
因为我们分辨机器大多是靠ip地址
就想能否在窗口的标题部分显示机器的ip就最好了

技术实现

bash支持环境变量PROMPT_COMMAND
将其设置为一个命令行字符串或者是包含命令行字符串的一个文件的文件名
命令行用来在显示prompt之前执行
而xterm又支持3种escape序列
可以用来更改xterm的“icon name”和”title”两者之其一或两者都改
还有
在redhat系列的机器上(redhat、fedora)
都支持文件/etc/sysconfig/bash-prompt-xterm来保存bash+xterm下的PROMPT_COMMAND环境变量的内容
结合这几点
我们就可以轻松实现“在窗口标题部分显示已登陆服务器的ip地址”这个功能
我当前用的是

echo -ne “\e]2;$(ifconfig | awk ‘/inet addr:/ && ! /inet addr:127\./ { sub (”addr:”, “”); print $2 }’ | sed -e :a -e ‘$!N;s/\n/\|/g;ta’):${PWD}\a”

这里的”\e]2″是xterm支持的第三种escape序列,用来设置窗口的标题
“$(.*)”的内容是shell命令,用来取出服务器的当前ip地址(除去127.x.x.x)列表,并用”|”连接起来
“${PWD}”是指当前的工作目录
“\a”是xterm支持的escape序列的结束符

引申一下

后来发现,所谓”xterm支持的3种escape序列”,基本上其他的term都支持
起码secure CRT里所带的term类型都支持(我测过)
而且redhat系列的服务器(redhat, fedora)除了支持/etc/sysconfig/bash-prompt-xterm外
还支持/etc/sysconfig/bash-prompt-screen、/etc/sysconfig/bash-prompt-default
用来存储当term类型是screen时和term类型不是xterm和screen时的PROMPT_COMMAND环境变量的值
于是乎

cp /etc/sysconfig/bash-prompt-xterm /etc/sysconfig/bash-prompt-default
cp /etc/sysconfig/bash-prompt-xterm /etc/sysconfig/bash-prompt-screen

这样的话
不管secure crt里term设成什么
都能在其标题里显示服务器ip

补充一下

为什么这里还有个term被设成screen的case呢
那是因为我们常用的命令screen
执行的时候会将环境变量PROMPT_COMMAND设成”screen”

在SecureCRT之类的终端仿真程序的标题显示远程server的全部ip地址

作为系统管理员

大概都有这种体会

管理的机器多了

经常同时用终端仿真程序连好几台机器

而且需要一会儿在这台上操作、一会儿又需要在那台机器上操作

很容易搞混机器:)

bash通过环境变量PROMPT_COMMAND支持在显示提示符PS1之前执行命令

而且xterm的终端类型又支持更改标题

所以……呵呵

我用bash的环境变量PROMPT_COMMAND+xterm

可以说已经解决了这个问题

具体的方法是

vi /etc/sysconfig/bash-prompt-xterm

添加一行,像下面这样:

echo -ne "\e]2;$(/sbin/ip -4 -o addr show | awk ‘{print $4}’ | awk -F/ ‘{print $1}’ | grep -v "^127\." | sed -e :a -e ‘$!N;s/\n/\//g;ta’)\a"

如果终端显示模式不是xterm的话

需要用命令export TERM=xterm将终端显示模式设置成为xterm

即可

其实这个问题也有别的解决方法

把每台机器的hostname设成这台机器的ip

然后再通过环境变量PS1来把ip地址显示在提示符里

不过这需要把环境变量PS1中的\h改成\H

\H能显示完整的ip地址

\h只能显示一个字节

像这样:

export PS1="[@\H \W]\\$ "