来源

1 简介

GNU Screen 是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行对话,并且在期间自由切换。GNU Screen 可以看做是窗口管理器的命令行界面版本。

GNU Screen 解决的痛点是:系统管理员通常需要使用 ssh 或者 telnet 远程登录到 Linux 服务器,有时候需要运行一些需要很长时间才能完成的命令,比如系统备份,ftp 传输等。一般我们会为每个这样的任务创建一个远程终端会话,必须要等到命令执行完成我们才能关闭这些会话,否则这个任务就会被中止。

GNU 提供了如下的功能:

  • 会话挂起和恢复: 只要 Screen 本身没有被中止,那么在其内部运行的会话都可以被恢复,这意味着及时会话执行过程中发生中断,用户也不会对已经打开的命令行会话失去控制,在会话中执行的命令也不会被意外中止。用户也可以主动执行 detach 命令将会话挂起。
  • 多窗口: Screen 环境下,所有的会话都独立地运行,并各自拥有自己的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并且可以自由地重定向各个窗口的输入和输出。窗口还可以被分区和命名。
  • 会话共享: Screen可以让一个或者多个用户从不同终端多次登录同一个会话,并共享会话的所有特性(比如可以看到完全相同是输出)。它同时提供了会话访问权限的机制,可以对会话进行密码保护。

2 命令形式

1
screen [-AmRvx -ls -wipe][-d <会话名称>][-h <行数>][-r <会话名称>][-s][-S <会话名称>]

参数说明:

  • -A  将所有的视窗都调整为目前终端机的大小。
  • -d <作业名称>  将指定的screen会话离线。
  • -h <行数>  指定会话的缓冲区行数。
  • -m  即使目前已在作业中的screen会话,仍强制建立新的screen会话。
  • -r <会话名称>  恢复离线的screen会话。
  • -R  先试图恢复离线的会话。若找不到离线的作业,即建立新的screen作业。
  • -s  指定建立新视窗时,所要执行的shell。
  • -S <会话名称>  指定screen会话的名称。
  • -v  显示版本信息。
  • -x  连接到之前未被detach的screen会话,多屏显示模式。
  • -ls或--list  显示目前所有的screen会话。
  • -wipe  检查目前所有的screen会话,并删除已经无法使用的screen会话。

3 Screen 的使用

Screen 程序有些 Linux 发行版不一定自带了,需要手动安装。例如 Ubuntu 上可以通过以下命令安装:

1
2
sudo apt update
sudo apt install -y screen

3.1 会话的创建

使用 Screen 管理会话,我们需要用 Screen 来创建会话:

1
screen -S name_of_session

这个命令可以为会话指定一个名称(直接调用screen创建的会话是没有名称的,不方便后续使用)。也可以在screen后面直接加上要执行的命令,可以直接为这个命令的进程创建一个匿名会话,当这个进程结束之后,该匿名会话即会结束。例如

1
screen vi somefile.txt

上面的例子中,screen会创建一个会话以执行vi命令。当vi执行完成以后,匿名会话也就结束了。

打开多个会话以后,可以使用 Ctrl-a w 列出当前的所有会话。如果使用文本终端,这个列表会列在屏幕左下角,如果使用X环境下的终端模拟器,这个列表会列在标题栏里。使用 Ctrl-a A 可以为当前的会话重新命名。

3.2 会话的挂起和恢复

你可以不中断screen窗口中程序的运行而暂时断开(detach)screen会话,并在随后时间重新连接(attach)该会话,重新控制各窗口中运行的程序。例如,我们打开一个screen窗口编辑/tmp/david.txt文件:

1
screen vi /tmp/david.txt

之后我们想暂时退出做点别的事情,比如出去散散步,那么在screen窗口键入C-a d,Screen会给出detached提示:

半个小时之后回来了,找到该screen会话:

1
screen -ls

重新连接对话

1
screen -r 12865

即可以恢复到之前的会话。注意这里 Screen 会为匿名会话创建一个数字的名称。

如果由于某种原因其中一个会话死掉了(例如人为杀掉该会话),这时screen -list会显示该会话为dead状态。使用screen -wipe命令清除该会话:

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

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

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

3.3 高级应用

3.3.1 会话共享

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

1
screen -x

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

3.3.2 会话锁定与解锁

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

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

3.3.3 发送命令到screen会话

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

screen -S sandy -X screen ping www.baidu.com