我用tmux有一段时间了,工作中会用到它的「会话保持」这一功能。在「跳板机」上建一个tmux会话,然后打开多个tmux window,在每个window下ssh连接到「开发机」,这是非常普遍的开发方式。下班时我只要按bind-key + d
脱离会话,电脑盖子一合就可以走人,当前机器上的多个ssh连接、打开的文档、运行的程序,都毫无「违和感」地同步「下班」。
第二天上班,我连接到「跳板机」,简单地执行2个命令,就可以重新快速挂载到昨天的tmux会话,之前建立的多个ssh连接、打开的文档、运行地程序,又都毫无「违和感」地同步「上班」,保持着昨天的状态(当然,运行着的程序没有退出的意思)。建立tmux会话时我并没有指定名称,重新挂载到会话上非常简单:
[xiaojie.zhang1@FS67 ~]$ tmux ls // 列出当前的tmux会话, ls = list session
0: 4 windows (created Wed Nov 6 18:37:38 2013) [181x50] (attached)
[xiaojie.zhang1@FS67 ~]$ tmux attach -t 0 // 挂载到第一个会话, -t 0
然而使用过程中遇到一个屏幕显示错乱的问题,在ssh连上「开发机」后,在「开发机」上用vim打开包含有中文的代码,就会出现:
万能的google会告诉我在tmux的配置文件中添加2个utf8的项:
[xiaojie.zhang1@FS67 ~]$ grep utf8 ~/.tmux.conf
setw -g utf8 on
set -g status-utf8 on
添加了之后就出现了中文「乱码」。
这2个配置项是不能解决问题的,乱码的因素有多个的好吗!!!!
- 终端的编码
- vim的编码
- tmux的编码
- 系统的locale
对于第1点, 我使用的iterm2,使用的字符编码为Unicode(UTF-8)
,嗯,已经是utf8了。
对于第2点,用vim的人都知道,vim读写一个文件时,使用设置项fenc
配置的编码,比如utf8;而vim显示文件内容,使用的是另一个设置项tenc
配置的编码,如果这2个配置的编码不一致,就能够看到vim的乱码。我先确认vim打开文件的编码和展示都用到utf8编码,两者编码一致:
:set fenc // 在vim命令行下
fileencoding=utf-8 // vim命令行下的输出
:set tenc // 同上
termencoding=utf-8
其实,不用tmux,从「跳板机」ssh连上「开发机」,再使用vim打开任何文本,都是不会乱码的(因为vim配置了正确的编码方式)。
对于第3点,tmux添加了utf8的编码也没有效果(其实这2个是设置tmux window的好吗), tmux的显示到底是根据哪里的配置??
到了第4点,确认是系统的locale问题了,tmux依赖于这些设置。由于我是在「跳板机」上使用tmux,tmux会使用到「跳板机」上的locale参数,查看:
[xiaojie.zhang1@FS67 ~]$ locale
LANG=en_US.en
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=C
果然!!!!于是再检查「跳板机」上是否已经安装zh_cn字符集:
[xiaojie.zhang1@FS67 ~]$ locale -a | grep -i zh_cn
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
没让我失望,有zh_cn.utf8
,添加到profile里吧:
[xiaojie.zhang1@FS67 ~]$ grep -i utf ~/.bash_profile
export LANG="zh_CN.UTF-8"
export LC_ALL="zh_CN.UTF-8"
kill掉tmux当前的会话,重新登录「跳板机」,新建一个tmux会话,再次确认tmux加载到新的locale
[xiaojie.zhang1@FS67 ~]$ tmux // 新建一个tmux会话和窗口
[xiaojie.zhang1@FS67 ~]$ locale // 进入tmux的窗口,再确认一次locale
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=zh_CN.UTF-8
tmux用到了utf8了, 这时再ssh连接到「开发机」,vim打开之前的文件,乱码已成往事,当然也不会显示错乱。
也就是说,若要「乱码」已成往事,需要4个地方的编码:
- 终端使用utf8编码(比如我使用iterm2,item2的终端字符集为Unicode(UTF-8) )
使用tmux的机器上(比如我这里的「跳板机」),其个人profile的locale使用utf8
[xiaojie.zhang1@FS67 ~]$ grep -i utf ~/.bash_profile export LANG="zh_CN.UTF-8" export LC_ALL="zh_CN.UTF-8"
每次登录都会export这2个环境变量,从而设置locale。
开发机」上vim设置utf8编码(linux)
xiaojie.zhang1@log83 ~$ grep enc ~/.vimrc set enc=utf8 set fencs=utf8,gbk,gb2312,gb18030,cp936
vim里其实没必要设置
tenc
,它会从fencs
列表中选一个适合的编码方式。tmux倒是可以不设置utf8
推荐一个讲解vim编码方式的普及blog: VIM乱码原因与解决方案
– EOF –