Linux 命令 - screen 和 tmux

1 screen 简介

screen 是 GNU 出品的一个工具,它实质上是复用终端,使得看上去每个 session 都有自己独立的控制终端一样(多个 session 所共享一个物理终端,且相互之间没有任何影响)

因此,可以在同一台主机上运行多个需要同一个控制终端的程序,而且方便用户控制。

在此基础上,它还可用于管理 session 与窗口,功能主要包括 session 保存与恢复,多窗口,session 共享等。这也是使用得最多的功能。

screen 可以使正在执行的程序脱离终端控制而继续正常执行,从而避免因关闭终端窗口或者 ssh 连接而产生的 SIGHUP 信号导致程序异常终止。

比如,当在终端中执行某个程序时,如果想关闭终端窗口而不影响程序的正常执行,则可以用 screen 将会话脱离终端并保存到本地。在合适的时候再打开终端窗口并用相应命令恢复该会话,使其重新拥有控制终端。

再比如,当通过 ssh 在远程主机上操作时,如果想在不影响操作的情况下断开 ssh 连接,或者关闭本地的伪终端窗口,甚至是关闭本地主机,则也可以用 screen 使会话脱离本地的控制而保存到远程主机上。在合适的时候再打连接 ssh 打开伪终端窗口并用相应命令恢复该会话,使其重新被本地控制。

比如说,你在公司里的电脑上的某个 session 里执行某个程序,然后想看看程序的执行结果。但是程序时间太长,而且时间太晚了,你又不想等着程序执行完才下班。这个时候,你只需要在家里通过 ssh 远程登录到你公司的电脑上,先 detach 掉这个 session,然后 reattach 到这个 session 就可以方便地继续工作了。

1.1 screen 与 daemon 和 nohup 的区别

当然,这种处理也可以通过 daemon 和 nohup 来完成。但是后两者并没有 screen 那样灵活。

  • daemon 没有控制终端,也不能再次获取控制终端,因此不受终端控制。所以看不到打印内容,而且不能交互。
  • 以 nohup 方式执行的进程是拥有控制终端的,因此可以通过终端来控制该进程。当终端退出或者其他情况导致发出 SIGHUP 信号时,该进程会自动忽略掉。如果是其父进程终止了,则该进程会被 init 进程接收。

    可以通过重定向的方式将打印结果写入文件中,但是不能方便地交互。
  • 而 screen 则非常灵活,可以通过简单的命令使会话拥有或脱离控制终端。即使会话不拥有控制终端,期间的打印结果也可以在拥有控制终端后方便地查看。

1.2 会话状态

  • attached。表明该会话拥有控制终端。
  • deattached。表明该会话不拥有控制终端。
  • dead。表明该会话因为某些原因已经不能再获取到,需要进行清理。

1.3 Command Character

又叫 escape character。默认的 command characterctrl+g,可以用来进入命令模式,松开后再键入其他命令来控制 session 以及窗口。后面会讲到。

1.4 screen 的配置

在用户主目录下建立一个名为 .screenrc 的文件,并编辑如下:

1
2
3
4
5
6
7
8
escape ^Gg

term screen-256color

altscreen on

hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{+b m}(%{W}%n*%f%t%?(%u)%?%{m})%{-b w}%?%+Lw%?%?%= %{g}][%{c} %D %M %d %{g}%c %{g}]'
  • 由于 shell 中 ctrl+a 是用来将光标移动到命令行的首字符的,为了避免冲突,这里将其用 ctrl+g 替换。
  • 默认情况下,screen 使用 8-color 终端,term screen-256color 则是开启 256-color。
  • 当从文本编辑器退出后,可能文本中的内容依然会在屏幕上。此时开启 altscreen 来避免这点。
  • hardstatus 用于在 session 中设置一些显示的状态。

当然,还可以进行复杂的配置。

2 screen 基本操作

2.1 创建 session

screen -S session名字

同时还会创建一个窗口,编号为 0。

2.2 列出当前的所有 session

screen -ls

2.3 detach 掉一个 session

screen -d session名 该操作会使指定 session 失去控制终端,状态变为 detached。并将前台恢复到创建该 session 之前的场景。

如果想 deatch 掉当前 session,则执行: screen ctrl+g d

2.4 reattach 一个 session

screen -r session名 该操作会使指定 session 重新拥有控制终端,状态变为 attached 状态。

还有一种经常用到的方法: screen -d -r session名 表示先 detach 掉指定的 session,然后 reattach 这个 session。

假设一台主机上某个会话的状态为 attached,当通过 ssh 连接到这台主机上并想控制这个 session 时(使其拥有本地的伪控制终端),那么直接执行: screen -r 该session名 是无效的,因为不能自动剥夺该 session 已经拥有的控制终端。此时只能用 -d -r 参数,先 detach 掉该会话,使其不拥有任何控制终端,然后再 reattach 该会话,使其拥有本地的伪控制终端。

2.5 关闭 session

ESC 或者 ctrl + d

该操作会关闭当前 session,并将前台恢复至创建该 session 前的状态。

2.6 某个 session 中窗口相关的操作

每个窗口都有一个编号,以及一个名字。

2.6.1 窗口的创建

ctrl+g c

2.6.2 查看所有窗口

ctrl+g "

2.6.3 选择窗口

上面的命令也可以用来选择窗口。

一般情况下,还可以通过如下命令进行选择: ctrl+g 窗口编号

2.6.4 窗口切换

ctrl+g SPACE 会按照编号递增的顺序进行切换。

ctrl+g n 同样如此。

切换到上一个编号的窗口: ctrl+g p

2.6.5 窗口重命名

ctrl+g A

2.6.6 关闭窗口

同一般关闭窗口的方法: exit 或者 ctrl + d

操作执行完后会将前台恢复到下一个窗口。

如果该窗口是所在 session 中唯一的窗口,则关闭窗口的同时也会关闭这个 session,并将前台恢复至创建该 session 前的状态。。

2.6.7 窗口划分成若干个窗格

这个功能在较旧版本的 Screen 中是不支持的。

垂直划分(左右划分成两个窗格): ctrl+g |

水平划分(上下划分成两个窗格): ctrl+g S

切换窗格(移动光标到某个窗格): ctrl+g TAB

增加窗格大小: ctrl+g :resize +N

减小窗格大小: ctrl+g :resize -N

划分了之后,就可以新划分处的窗格里新建窗口了: ctrl+g c

删除窗格时,先将光标定位到所要删除的窗格里,然后执行: ctrl+g :remove

2.7 拷贝模式

如果要查看某个 session 在失去控制终端期间所有打印的内容,则可以通过进入拷贝模式查看。 ctrl+g [

相关的查看操作同 Vim 类似,这里不再赘述。

然后按下 SPACE 开始进行拷贝,再按下 ENTER 拷贝结束。

粘贴时执行如下命令: ctrl+g ]

2.8 显示所有键绑定信息

ctrl+g ?

2.9 清理状态为 dead 的会话

screen -wipe

2.10 session 的嵌套

也就是说,可以在一个 session 中在创建另外多个 session。此时,一般的 command character 只作用于最外层的 session。要想控制内层的 session,则需要做一些特殊处理。

比如有三层 session,当前正在最内层 session 里。

如果要想 detach 第二层 session,则执行如下的 command character: ctrl+g 然后再执行: gd

如果想作用于最内层的 session,则执行如下的 command character: ctrl+g 然后再执行: ggd

3 screen 会话共享

当某个用户在一台主机上建立了一个 session 之后,其他用户也可以共享该 session,也即这个 session 被多个控制终端所共享。执行如下命令: screen -x session名 该 session 必须是存在的。

之后,其中任何一个用户在该 session 里的操作,其他用户都是能够看到的。

4 tmux 简介

Tmux 是另外一款非常强大的终端复用器,Screen 有的功能它都包含在内。

除此之外,Tmux 还在以下方面胜过 Screen:

  • Screen 对 xterm 支持得不是很好,而 Tmux 则相反;
  • tmux 对在窗口中再分成若干个窗格具有更好的支持。

tmux 的常用配置见: gpakosz - .tmux

5 tmux 基本操作

假设 prefix character (类似于 screen 中的 command charcter) 为 ctrl+g

5.1 session 相关操作

创建一个 session: tmux new -s session名

重命名一个 session: tmux rename -t session名

显示所有 session: tmux ls

detach 一个 session: ctrl+g d

reattach 一个 session: tmux attach -t session名

对于一个状态为 attached 的 session,在 reattach 时,tmux 与 screen 的处理有些不一样。 后者是不能强行 detach 掉该会话已获得的控制终端,除非加上 -d 参数;而前者则默认采用会话共享

5.2 窗口 (window) 相关操作

新建一个窗口: ctrl+g c

重命名一个窗口: ctrl+g ,

显示当前 session 的所有窗口,并可切换至某个窗口: ctrl+g w

切换到下一个窗口: ctrl+g n

切换到上一个窗口: ctrl+g p

切换到指定编号的窗口: ctrl+g 数字

关闭当前窗口: ctrl+g &

5.3 窗格 (pane) 相关操作

水平分割(两个上下的窗格): ctrl+g "

垂直分割(两个左右的窗格): ctrl+g %

切换窗格: ctrl+g 上下左右方向键

查看所有窗格的编号: ctrl+g q

暂时将一个窗格尺寸调至最大: ctrl+g + 再执行这个命令即可恢复回来。

与上一个窗格交换位置: ctrl+g <

与下一个窗格交换位置: ctrl+g >

将当前窗格向下扩大 1 格: ctrl+g :resize-pane -D

将当前窗格向上扩大 1 格: ctrl+g :resize-pane -U

将当前窗格向左扩大 1 格: ctrl+g :resize-pane -L

将当前窗格向右扩大 1 格: ctrl+g :resize-pane -R

当然,也可以指定具体的格数。比如向下扩大 10 格子: ctrl+g :resize-pane -D 10

关闭窗格: ctrl+g x

5.4 拷贝模式

进入模式模式: ctrl+g [

之后点击 SPACE 开始选择,然后点击 ENTER 选择结束。

粘贴: ctrl+g ]

查看粘贴缓冲列表,并选择粘贴缓冲进行粘贴: ctrl+g P

5.5 鼠标模式

进入/退出鼠标模式: ctrl+g m

鼠标模式开启后,可以很方便地选择窗口,窗格,调整窗格尺寸,滚动屏幕,拷贝等。

5.6 其他

列出所有快捷键: ctrl+g ?

在窗格中央显示时钟: ctrl+g tESC 退出。


Reference