screen 作为 Linux 的 tty 模式下面好用的终端复用工具,具有很强大的功能。在 ssh 远程连接的时候,screen 命令可以避免因为意外掉线导致当前执行的命令终止。原因在于,ssh 远程连接时,所有进程是在 ssh 进程下面执行的,一旦掉线,ssh 进程随之终止,其下运行的进程也一并终止。而 screen 建立的窗口中执行的进程则是在 screen 下面执行,因此即使ssh意外中断,也不会影响到 screen 建立的窗口下面进程的运行。
screen 的基本用法
首先,最基本的自然是新建一个窗口。
screen –S <name>
<name> 为指定窗口的名称,此时自动对接(attach)到新的窗口。
直接输入 screen 也可以新建一个窗口。
screen的操作指令以 Control-A(以下简称 C-a)开头,这被称之为按键绑定。例如,最常用的就是按下 C-a 之后,再按 d,即可分离(detach)当前窗口。所有的按键绑定可以通过 C-a ? 进行查询。常见的按键绑定如下。
C-a ? 显示所有键绑定信息 C-a w 显示所有窗口列表 C-a C-a 切换到之前显示的窗口 C-a c 创建一个新的运行shell的窗口并切换到该窗口 C-a n 切换到下一个窗口 C-a p 切换到前一个窗口(与C-a n相对) C-a 0..9 切换到窗口0..9 C-a a 发送 C-a到当前窗口 C-a d 暂时断开screen会话 C-a k 关掉当前窗口 C-a [ 进入拷贝/回滚模式
当一个窗口处于分离态时,分离的原因有可能是我们手动 detach ,也可能是 ssh 断线,这时候如果想要返回刚才的窗口,只需要使用:
screen –r <name>
你可能说,我忘了窗口的名字,甚至我根本就没有起名字,想要知道窗口的名字;又或者,我想知道现在到底开了几个窗口,这时候,就需要用下面的命令来列出所有窗口:
screen –ls
窗口的名字在没有指定的时候默认按下面的格式命名:pid.tty.host
。在指定名字后,为 pid.<name>
。
如果一个窗口我用完了,想关闭,这时候在窗口内部,通过C-a k即可关闭,也就是关掉这个窗口。
以上可以说是 screen 命令的基本用法。
screen 的进阶用法
通过 screen –S
创建的窗口会默认与之对接(attach),如果不想对接,我们可以用下面的命令创建一个分离的(detached)窗口:
screen –dmS <name>
如果我想在一个 Bash 脚本里面使用 screen 创建一个窗口,然后在窗口里面执行一些命令,问题就来了。通过 screen –S
创建 window 后默认会进入这个 window,进入后脚本接下来的命令并不会在建立的这个窗口中运行。而是在原来的提示符下面运行。由此我们也可以看出,screen 的确只是创建了一个全屏的窗口并覆盖了屏幕而已。通过刚才的 screen –dmS <name>
创建的窗口如果再 screen –r
进去也不会执行。
这时候需要用到的是 -X
选项,这个选项可以向一个窗口发送指令。
要往一个窗口中发送文本,可以用下面的命令:
screen –S <name> -X stuff `text`
stuff 可以向由 -S
指定的窗口发送文本,当你再次对接(attach)之后,你会发现提示符后面已经有了“text”。
但是,我们想的是执行某个命令,如果还要进去再手动按回车才能执行显然不能满足我们的需求,这时候我们只要用下面的命令即可:
screen -S <name> -X stuff `printf "<command>\r"`
以上命令可以向指定窗口发送指令,将“<command>\r”打印至标准输出,“\r”为回车符,于是,命令便被执行了。
上述方法适合于单条命令,若中间有空格,可能会失败,下面的命令可以用于执行更复杂的命令
screen -S centos -X stuff $'<command> \n'
或者
screen -S new_screen -X stuff "cd /dir "
当我们想要关掉一个窗口的时候,可以向该窗口发送quit指令:
screen -S <name> -X quit
更为详细的用法,参见 screen 的 manual(在线版)。
参考资料:
[1] screen manual
[2] https://www.ibm.com/developerworks/cn/linux/l-cn-screen/
[3] http://stackoverflow.com/questions/7049252/how-to-create-a-screen-executing-given-command