0. 概述

说起 *nux 系统,让人想到的第一个东西可能就是命令行了,作为 linux 的表示层,各种 shell 为我们提供了高效的工作工具的同时,也让我们能够更加简单得控制我们自己的系统。但是,工具是死的,人却是活的,一个东西能够怎么用,不在于这个东西自身的功能如何,而是看使用它的人玩的方式。相信很多同学都有远程 SSH 上服务器的经验,不同于桌面版的 Shell,远程 SSH 的 shell 虽然在大多数情况下和本地差不多,但是最根本的问题在于本身就是通过网络进行连接的,所以就会出现很多和网络相关的问题。

这里大概的考虑一下这些问题,我们在 shell 中运行一个 cmd,比较通用的实现方式都是通过 fork-exec 的方式运行,这在本地的话,基本上只要不关闭 terminal 都能让 cmd 自然运行结束(正常结束/异常结束),但是,如果我们通过 ssh 远程到服务器的话,除了我们不关闭连接的 terminal 之外,还可能出现网络问题,导致 ssh 连接中断,从而导致远程执行的 cmd 出错。有问题就有解决方法,一开始人们可能最简单粗暴的方式就是使用类似于后台执行的方式运行,也就是使用 nohup 命令,例如下面这个:

$ nohup python /home/liqiang.io/webserver/server.py > /tmp/liqiang.io.log 2>&1 &

这里就不细讲这样实现的原理了,有兴趣的同学大可以去看一下 nohup 的原理,无非就是屏蔽信号这些。这里说一下这里的问题,这个方式有个问题就是我们将 cmd 放到后台去执行了,然后看日志啥的需要去看文件,当然,你可以使用这条命令去看:

$ tailf /tmp/liqiang.io.log

这在一般情况下也没啥毛病,但是,对于我习惯于使用高亮的人来说,这就遗失了很多信息。所以我就找有没有什么好一些的工具可以帮助我更好得解决这个问题,还记得那是大三的时候,跟了一个老师(它翻译了一本书《数字设计和计算机体系结构》,后面好像给了 vczh,也就是你们熟悉的知乎轮子哥),在做他的实验项目的时候遇到了这个问题,当时一个师姐给我介绍了 screen 这个命令,下面就来看看 Screen 这个命令。

1. screen

screen 是一个软件,只要它还在目标服务器上运行,无论是在服务器的键盘上运行的 cmd 还是远程连接到服务器上运行的命令,你都可以在任一时刻和任一客户端恢复运行。或许这么说你可以不太理解,我举个例子,假设你想在服务器上编译一个软件,就当是 nginx 吧,可是现在时间不早了,再晚一点回家里停车位就要没位了,但是回家需要时间啊,如果在我回家这段时间内能让它编译,然后我回到家应该就差不多可以用了,不是很惬意的事情?在这个时间可以这么操作,你登录上一台服务器,然后使用 screen 命令创建一个 session,然后再 session 里面编译 nginx,当编译的命令敲完之后,你就可以随意关掉这个 terminal 了,然后回家,回到家之后,再连上服务器,同样得,使用 screen 命令恢复之前创建的 session 你会发现当前的 terminal 和你回家之前见到的一模一样,屏幕输出什么的都在,就像刚刚自己才执行的一样。

其实 screen 的原理不难,我没有看过它的源代码,但是我猜测可能是 screen 自身进程就是以守护态运行,然后对于每个 session,都是单独管理。当然 screen 做的事情不仅仅是 session 管理,它还能管理 window,毕竟它的名字就叫 screen 嘛,废话不多说,先来看看 screen 命令的参数:

$ created by https://liqiang.io
$ screen -h
-d session  离开 screen session,不关闭
-m          即使目前已在 session,仍强制建立新的 session
-r session  恢复到对应的 session
-R          先试图恢复 session,若找不到 session,即建立新的
-S session   设置 session 的名称
-x           恢复之前离线的 session
-ls          显示当前所有的 session
-wipe        检查目前所有的 session 并删除无法使用的

通过这些命令组合,我们就可以轻松得控制我们的 sesion 了,这样就成功得达到了目的。但是,随着玩了一阵的 screen 之后,虽然发现它也有不错的 window 的管理功能,但是却不是太让人舒服,但是一直没有去解决这个问题,因为后续一直使用 windows 比较多。直到后面用多了 Mac 之后,这个痛点终于让我不舒服了,于是乎我又开始寻找替代品了,所以另外一款不错的工具又被我了解到了——Tmux。

1.1 screen 翻页

通过 screen 管理会话的时候,我发现我默认的 shell 翻页不能用了,也就是说没法回去看前面的输出结果,很不方便,于是找了一下解决办法:

1.2 退出 session 但是不关闭

2. Tmux

其实讲道理,tmux 应该可以认为是 screen 的增强版,因为 screen 的功能都可以在 tmux 中找到,我个人的看法是 tmux 比较有特色的功能就是:

其他倒还好,对于 tmux 其实也没有太多好说的,下面就看下常用的快捷键,首先需要说一下的就是在 Mac 下面的前置快捷键是:^b,也就是 Ctrl + b(和 Ecmas 有点像?)

2.1 window 操作

Ctrl+b %        左右分屏
Ctrl+b "        上下分屏
Ctrl+b x        关闭当前 window
Ctrl+b {        当前 windwo 前移
Ctrl+b }        当前 window 后移
Ctrl+b ;        切换上次使用的 window
Ctrl+b o        切换下一个 window,也可以使用上下左右方向键来选择
Ctrl+b z        最大化当前 window,再按一次恢复
Ctrl+b q        显示所有 window 的序号,在序号出现时按下对应的数字,可以切换到对应 window

更多的功能就不描述了,如果你想探索更多的玩法,在文章后面我列举了一些我平时看过的一些文章,你可以根据需要自行阅读。

3. 我的选择

其实从尝试 tmux 开始到现在的两年多里,我并没有坚持用 tmux,因为我使用的 terminal 是 iTerm2,自身就带分屏等功能,而且还具备很多比 tmux 更好用的功能,比如可以简单得配置快捷键这些。但是 screen 却是我用得非常多的,因为其轻便性,我推荐一个比较有意思的用法:屏幕共享,使用 screen 你可以远程和其他人一起看一下 terminal,这个有什么好处呢,例如 debug、review、interview 的时候我觉得都很有用。

4. Reference

  1. Installing tmux 2.2
  2. Linux终端分屏工具tmux快捷键备忘
  3. 优雅地使用命令行:Tmux 终端复用
  4. iterm2有什么酷功能?
  5. Tmux - Linux从业者必备利器
  6. screen命令