.-- .. - .... .-.. --- ...- .

home archive about

GNU Screen 使用入门

24 Jul 2011

前些天开始学习使用 GNU Screen 程序,发现这个工具在管理服务器时候确实挺方便的,于是写一篇文章总结一下,顺便介绍 Screen 的基本使用方法。

简介

GNU Screen 是一个基于文本的全屏窗口管理器,一个 Screen 会话可以在一个物理终端上模拟多个窗口,每个窗口中可以运行不同的进程。 Screen 一个典型的应用就是在其创建的虚拟终端窗口中运行交互性的 Shell 程序,例如 bash,这样就可以在一个终端上打开多个 bash 进行不同的操作了。

举个例子,你可以使用 SSH 登录到你的服务器,然后打开一个 Screen 会话,使用它创建多个窗口。每个窗口都有一个独立的 bash,然后就可以在同一个 SSH 会话中进行不同的操作, 譬如一个窗口编译,一个窗口写代码,另一个窗口挂着 IRC,每个窗口内的进程都是独立的,还可以在这些窗口直接随意切换。 Screen 为每个窗口都保存回滚历史,而且你还可以在不同的窗口中进行复制粘贴等操作。 当然 Screen 的功能远不止多窗口这么简单,下面我对这个强大的程序进行一下简单的介绍,虽然不会很全面,但也可以拿来入门。 关于 Screen 程序更多的功能当然还是在它的帮助手册里和Google上了。

安装和启动

Screen 这么著名的程序,Linux 各种发行版自然都有,实在没有也有源代码下载,反正我的 Fedora 和 CentOS 是没有必要自己编译了:

yum install screen

就是这么简单。

安装完成后,直接敲命令 screen 就可以启动它。但是这样启动的 Screen 会话没有名字,实践上推荐为每个 Screen 会话取一个名字,方便分辨:

screen -S session_name

Screen 启动后,会创建第一个窗口,也就是窗口 No. 0,并在其中打开一个系统默认的 shell,一般都会是 bash。 所以你敲入命令 screen 之后,会立刻又返回到命令提示符,仿佛什么也没有发生似的,其实你已经进入 Screen 的世界了。 当然,也可以在 screen 命令之后加入你喜欢的参数,使之直接打开你指定的程序,例如:

screen python
screen vi foo.c

这两个命令一个直接启动 python 的交互窗口,另一个打开 vi 编辑 foo.c 这个文件。

查看帮助

Screen 程序使用 Ctrl+a(缩写做 C-a)作为其快捷键的前缀。快捷键 C-a ? 可以用来查看 Screen 的一个帮助页面,也就是先同时按下 Ctrl 和 a,然后按 ?。

Emacs 和 bash 中,C-a 快捷键用于回到行首。但是在 Screen 中,C-a 就会被 Screen 吞掉而无法直接发送给 Emacs 或 bash。 要在 Emacs 或者 bash 等程序中使用 C-a,只需要按 C-a a,这个快捷键把 C-a 本身发送给 Screen 中运行的程序,避免快捷键的冲突。

使用多窗口

创建窗口

启动 Screen 以后,可以在任何需要的时候打开一个新的窗口,新窗口中可以运行新的程序,完全不影其他窗口中程序的运行。 创建窗口快捷键是 C-a c。新窗口创建后就会直接跳转到其中,窗口里默认会打开新的 shell,你可以在这个新的 shell 中进行其他的操作。

还有另一种创建窗口的方法,就是在 Screen 会话的一个 Shell 窗口中运行 screen 命令。 听起来有点绕,其实就是如果你已经在一个 Screen 会话中了,那么再在其中命令 screen,不会递归地在其中产生新的 Screen 会话,而是会在已有的 Screen 会话中创建一个新的窗口。 有了这个方法,就可以像启动 Screen 会话时一样,直接指定新窗口中运行的程序了。

关闭或杀死窗口

正常情况下,当你退出一个窗口中最后一个程序(通常是 bash)后,这个窗口就关闭了。 另一个关闭窗口的方法是使用 C-a k,这个快捷键杀死当前的窗口,同时也将杀死这个窗口中正在运行的进程。

如果一个 Screen 会话中最后一个窗口被关闭了,那么整个 Screen 会话也就退出了,screen 进程会被终止。

查看窗口和窗口命名

打开多个窗口后,可以使用快捷键 C-a w 列出当前所有窗口。如果使用文本终端,这个列表会列在屏幕左下角,如果使用 X 环境下的终端模拟器,这个列表会列在标题栏里。 窗口列表的样子一般是这样:

0$ bash  1$ bash  2$ bash  3-$ bash  4*$ bash

这个例子中我开启了五个窗口,其中 '*' 号表示当前位于窗口 4,'-' 号表示上一次切换窗口时位于窗口 3。

也可以使用 C-a " 来查看当前 Screen 程序中的所有窗口,这个快捷键会将所有窗口在单独一个屏幕上列出来,可以使用 'vi-like' 的快捷键 'j' 和 'k' 在窗口之间选择,回车进入所选窗口。

Screen 默认会为窗口命名为编号和窗口中运行程序名的组合,上面的例子中窗口都是默认名字。练习了上面查看窗口的方法,你可能就希望各个窗口可以有不同的名字以方便区分了。 可以使用快捷键 C-a A 来为当前窗口重命名,按下快捷键后,Screen 会允许你为当前窗口输入新的名字,回车确认。

在窗口之间切换

在 Screen 会话中,可以很方便的在各个窗口之间进行切换。下面总结几个常用的切换快捷键:

当然,上一小节的 C-a " 快捷键,可以列出当前会话中的窗口,也可以实现切换到指定窗口的功能。

会话操作

会话分离和恢复

Screen 一个比较强大也比较实用的功能,就是可以分离和恢复会话 (Detaching/Reattaching)。设想这样的情况,你在实验室的机器上打开 Screen,在其中一个窗口里写代码, 另一个窗口里编译一个大工程,比如 Linux 内核。然后十点半要封楼了,楼管大爷催你回寝室。 如果不是在 Screen 中工作的话,那么你可能需要退出正在写代码的编辑器,而且回寝室远程登录到实验室机器以后,还要通过 PS 等其他非常手段查看编译是否完成了。

有了 Screen,就可以从容多了,只需按下 C-a d,然后关闭显示器就可以回寝室去了。这个快捷键将当前终端与其中的 Screen 会话分离开,这个 Screen 会话的状态就变成了 'detached'。 此外,还可以使用 C-a D D 快捷键,将当前终端与 Screen 分离后,还会直接退出当前终端上的登录。回到寝室后,再用 SSH 登录实验室主机,命令:

screen -r

就可以看到你之前在实验室看到的 Screen 会话了,所有的窗口都是离开前留下的状态。

上述 Reattach 命令没有指定恢复哪个 Screen 会话,如果同一个 Linux 用户打开了多个 Screen 会话,则可以通过制定会话名称来恢复。 首先,下面命令可以查看属于当前用户的所有 Screen 会话:

screen -ls

这个命令有类似下面的输出:

There are screens on:
        14715.second    (Detached)
        14588.first     (Detached)
2 Sockets in /var/run/screen/S-yuliang.

其中每个会话的都由其 PID 和名称来标识,可以通过指定 PID 或名称来恢复指定的 Screen 会话:

screen -r 14715
screen -r first

当然,如果你在实验室没有分离一个 Screen 会话,就无从恢复会话了。这时可以使用下面命令强制将这个会话从它所在的终端分离,转移到新的终端上来:

screen -d
screen -r

或者可以直接命令:

screen -dRR

也可以一次性完成上述 Detach + Reattach 的工作。

会话共享

还有一种比较好玩的会话恢复,可以实现会话共享。假设你在和朋友在不同地点以相同用户登录一台机器,然后你创建一个 Screen 会话,你朋友可以在他的终端上命令:

screen -x

这个命令会将你朋友的终端 Attach 到你的 Screen 会话上,并且你的终端不会被 Detach。 这样你就可以和朋友共享同一个会话了,如果你们当前又处于同一个窗口,那就相当于坐在同一个显示器前面,你的操作会同步演示给你朋友,你朋友的操作也会同步演示给你。 当然,如果你们切换到这个会话的不同窗口中去,那还是可以分别进行不同的操作的。

会话锁定和解锁

Screen 允许使用快捷键 C-a s 锁定会话。锁定以后,再进行任何输入屏幕都不会再有反应了。但是要注意虽然屏幕上看不到反应,但你的输入都会被 Screen 中的进程接收到。 快捷键 C-a q 可以解锁一个会话。

也可以使用 C-a x 锁定会话,不同的是这样锁定之后,会话会被 Screen 所属用户的密码保护,需要输入密码才能继续访问这个会话。

发送命令到 Screen 会话

在 Screen 会话之外,可以通过 screen 命令操作一个 Screen 会话,这也为使用 Screen 作为脚本程序增加了便利。 关于 Screen 在脚本中的应用超出了入门的范围,这里只看一个例子,体会一下在会话之外对 Screen 的操作:

screen -S session_name -X screen ping gnailuy.com

这个命令在一个叫做 session_name 的 Screen 会话中创建一个新窗口,并在其中运行 ping 命令。

退出 Screen 会话

除了依次退出/杀死当前 Screen 会话中所有窗口这种方法之外,还可以使用快捷键 C-a :,然后输入 quit 命令退出 Screen 会话。 需要注意的是,这样退出会杀死所有窗口并退出其中运行的所有程序。其实 C-a : 这个快捷键允许用户直接输入的命令有很多,包括分屏可以输入 split 等, 这也是实现 Screen 功能的一个途径,不过个人认为还是快捷键比较方便些。

屏幕分割

现在显示器那么大,将一个屏幕分割成不同区域显示不同的 Screen 窗口显然是个很酷的事情。可以使用快捷键 C-a S 将显示器水平分割,Screen 4.00.03 版本以后,也支持垂直分屏,快捷键是 C-a |。分屏以后,可以使用 C-a <tab> 在各个区块间切换,每一区块上都可以创建窗口并在其中运行进程。

可以用 C-a X 快捷键关闭当前焦点所在的屏幕区块,也可以用 C-a Q 关闭除当前区块之外其他的所有区块。关闭的区块中的窗口并不会关闭,还可以通过窗口切换找到它。

C/P 模式和操作

复制和粘贴

Screen 的另一个很强大的功能就是可以在不同窗口之间进行复制粘贴了。使用快捷键 C-a <Esc>或者 C-a [ 可以进入 'copy/paste' 模式,这个模式下可以像在 vi 中一样移动光标,并可以使用空格键设置标记。其实在这个模式下有很多类似 vi 的操作,譬如使用 '/' 进行搜索,使用 'y' 快速标记一行,使用 'w' 快速标记一个单词等。 关于 C/P 模式下的高级操作,其文档的这一部分有比较详细的说明。

一般情况下,可以移动光标到指定位置,按下空格设置一个开头标记,然后移动光标到结尾位置,按下空格设置第二个标记,同时会将两个标记之间的部分储存在 'copy/paste buffer' 中,并退出 'copy/paste' 模式。在正常模式下,可以使用快捷键 C-a ] 将储存在 buffer 中的内容粘贴到当前窗口。

查看各个窗口的历史

使用 Screen 时,每个虚拟终端的历史输出都会显示在物理终端的回滚缓冲中,因此使用物理终端自带的回滚功能会查看到不同窗口中内容的混杂。 Screen 为每个虚拟终端都设有有自己的回滚缓冲,其实在上面提到的 'copy/paste' 模式中,就可以查看到一个窗口单独的缓冲。

监视窗口中的活动

使用 Screen 时,可以将编译放在后台窗口,然后在其他窗口进行其他工作。如果编译耗时很长,那么可以使用 Screen 的监视功能,在编译完成后,窗口不再活动后,为我们做出提示。 可以使用 C-a _ 快捷键监视一个窗口,如果这个窗口超过 30 秒没有任何活动,就为用户做出提示。

相反的,可以使用 C-a M 监视一个窗口,如果这个窗口有活动,为用户做出提示。这个功能可以用于监视 IRC 频道是否有新的谈话等。

配置文件

同大多数 UNIX 程序一样,GNU Screen 的另一个强大之处,在于其灵活强大的的配置文件。 配置文件一般位于用户家目录,文件名是 .screenrc。在配置文件中可以进行许多自由灵活的配置,来实现更大程度的个性化。 由于本文是入门文章,就不涉及太多高深的话题,而且 Screen 的默认配置已经非常有用,所以关于配置文件的内容就留待以后再续。

Creative Commons License

comments powered by Disqus