######################################################
终端多窗口管理神器
------tmux byobu screen terminator谁与争锋之screen篇
#########################################################
###################
GNUscreen命令详解
###################
#######
引 言:
#######
"你是不是经常需要 SSH 或者 telent 远程登录到 Linux 服务器?你是不是经常为一些长时间运行的任务而头疼,比如系统备份、ftp 传输等等。通常情况下我们都是为每一个这样的任务开一个远程终端窗口,因为他们执行的时间太长了。必须等待它执行完毕,在此期间可不能关掉窗口或者断开连 接,否则这个任务就会被杀掉,一切半途而废了。
元凶:SIGHUP 信号
让我们来看看为什么关掉窗口/断开连接会使得正在运行的程序死掉。
在Linux/Unix中,有这样几个概念:
* 进程组(process group):一个或多个进程的集合,每一个进程组有唯一一个进程组ID,即进程组长进程的ID。
* 会话期(session):一个或多个进程组的集合,有唯一一个会话期首进程(session leader)。会话期ID为首进程的ID。
* 会话期可以有一个单独的控制终端(controlling terminal)。与控制终端连接的会话期首进程叫做控制进程(controlling process)。当前与终端交互的进程称为前台进程组。其余进程组称为后台进程组。
根据POSIX.1定义:
* 挂断信号(SIGHUP)默认的动作是终止程序。
* 当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)。
* 如果会话期首进程终止,则该信号发送到该会话期前台进程组。
* 一个进程退出导致一个孤儿进程组中产生时,如果任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中所有进程。
因此当网络断开或终端窗口关闭后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出。
如果我们可以忽略SIGHUP信号,关掉窗口应该就不会影响程序的运行了。nohup命令可以达到这个目的,如果程序的标准输出/标准错误是终 端,nohup默认将其重定向到nohup.out文件。值得注意的是nohup命令只是使得程序忽略SIGHUP信号,还需要使用标记&把它放 在后台运行。"
此段引自前辈:田 强 (
tianq@cn.ibm.com
), 软件工程师, IBM中国软件开发中心 2007 年 7 月 31 日
的确,相信很多朋友都有过这样的经历。在使用telnet或SSH等远程登录linux时,在服务器上跑一些程序,有时候得跑很长时间(超过12小时)这 时如果程序没结束就退出远程管理终端,远程跑的程序很有可能就此挂点;此外,可能也经常需要在多个程序之间来回切换,怎么办?ctrl-z和fg、bg nohup?这些太麻烦,且时常捉襟见肘。更让人无法忍受地,如果连接非正常中断,重新连接时,系统将开启一个新的session,无法恢复原来的 session。
以前常用的解决方式是用命令nohup但nohup有很多解决不了的问题。值得庆幸的是GNU screen命令可以很好地解决这个问题。
linux的screen命令,对于远程登录来说,不仅提供了类似于nohup的功能,而且提供“多个桌面”的功能。screen工具是一个终端多路转接器,在本质上,这意味着你能够使用一个单一的终端窗口运行多终端的应用。
简单讲,screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。Screen中有会话(session)的概念,用户可以在一个 screen会话中创建多个screen窗口(window),在每一个screen窗口中和实际操作一个真实的telnet/SSH连接窗口没什么区 别。
#######
安 装:
#######
流行的Linux发行版(例如Red Hat,CentOS,fedora,ubuntu,openSUSE等等)通常会自带GNU screen实用程序。如果没有的话,可以从GNU screen的官方网站下载。
通常对于rpm系列的linux,安装screen,可以通过yum在线安装或本地ISO yum源安装,这里就不多赘述
sudo yum install screen #yum在线安装
sudo yum --disablerepo=\* --enablerepo=c6-media install screen
#本地ISO yum源安装
对于deb系列,如ubuntu,也可以通过官方源在线安装和本地ISO源安装
sudo apt-get install screen
#########
语 法:
#########
screen [-AmRvx -ls -wipe][-d ][-h ][-r ][-s ][-S ]
补充说明:
screen为多重视窗管理程序。此处所谓的视窗,是指一个全屏幕的文字模式画面。
参 数:
-4 使用ipv4
-6 使用ipv6
-a all,包括所有的功能
-A 将所有的视窗都调整为目前终端机的大小。
-c file 使用配置文件file,而不使用默认的~/.screenrc
-d|-D [pid.tty.host] 将指定的screen会话暂时中断,可通过screen -r来恢复。
-dmS name 启动一个初始状态断开的screen会话daemon
-D 暂时中断会话并注销
-e xy 改变命令行映射
-h lines 指定历史回滚缓冲区大小为lines行
-f 开启follow control
-i 当follow control开启时,中断输出
-l 开启登陆模式
-list或-ls 显示目前所有的screen会话,格式为pid.tty.host
-L 开启output日志功能
-m 忽视$STY变量,强制新建screen会话。
-O 指定输出来代替默认的VT100
-p window 如果存在己经命名过的window则选定所指定的window
-q 安静启动。如果不成功则返回非零值
-r sessionowner/ [pid.tty.host] 重新连接一个断开的会话。多用户模式下连接到其他用户screen会话需要指定sessionowner,需要setuid-root权限
-R 先试图恢复中断的会话。否则建立新的screen会话。
-s shell 指定screen会话所要执行的shell。
-S sessionname 创建screen会话时为会话指定一个名字
-t title 设置window的标题
-T term 使用指定的term来作为$TERM对对所有的window而言,而不是screen
-U 告诉screen使用UTF-8编码
-v 显示screen版本信息
-wipe 清除已经无法使用的screen会话,格式为pid.tty.host
-x 多重显示模式,用于多会话多用户同时联机
-X 在指定的会话中自动运行一个screen命令
##############
常用参数举例:
##############
screen -S hello -> 新建一个叫hello的session
screen -ls -> 列出当前所有的session
screen -r hello -> 恢复hello这个session
screen -d hello -> 远程detach某个session
screen -d -r hello -> 结束当前session并恢复hello这个session
##################
screen键绑定(默认)
##################
#screen的默认控制符,所有的快捷键都由^A开始
Commandkey: ^A Literal ^A: a
#帮助及退出相关window
C-a ? (help) 显示键绑定列表帮助
C-a C-\ (quit) kill掉所有的window并退出screen
C-a k|C-k (kill) kill掉当前window
C-a X (remove) kill掉当前分割的window
C-a Q (only) 关闭所有分割的window,仅保留当前的window
#命令行模式
C-a : (colon) 命令行模式
如:
C-a :screen 新建 screen 终端,并运行命令
C-a :resize 改变当前窗口高度为
C-a :quit 退出 screen,将关闭所有 screen 终端
#新建和切换window
C-a c|C-c (screen) 新建window
C-a h|p|C-p (prev) 切换到上一个window
C-a space|n|C-n (next) 切换到下一个window
C-a ’ (select) 在提示符下交互地输入要切换的window编号来切换window
C-a " (windowlist -b) 列出当前session下所有的window以供切换
C-a [0-9] (select [0-9]) 切换到编号为[0-9]的window
C-a - (select -) 切换到一个空白的window
C-a C-a (other) 在两个最近使用的window间切换
C-a A (title) 重命名当前所在的window
#分割窗口及切换
C-a S (split) 横向分割当前window
C-a tab (focus) 在横向分割的窗口间进行切换
C-a F (fit) 将所有window的尺寸调整到同当前window一样
#中断session
C-a d|C-d (detach) 暂时中断当前session,即将目前的session放到后台执行,并回到shell状态,此时在screen session里每个window内运行的process(无论前台/后台)都在继续执行,即使logout也不影响。
C-a D (pow_detach) 中断session并注销
#显示相关信息
C-a , (license) 显示screen的简介信息
C-a v (version) 显示版本信息和编译日期
C-a i|C-i (info) 显示当前窗口的一些信息
C-a N (number) 显示当前window编号及标题
C-a m|C-m (lastmsg) 显示上一次的提示信息
C-a t|C-t (time) 显示系统时间和平均负载
C-a w|C-w (windows) 显示所有己开启的window列表
C-a * (displays) 显示登录信息
#关闭或开启标准输出
C-a q|C-q (xon) 向当前window发出一个control-q信号
C-a s|C-s (xoff) 向当前window发出一个control-s信号
#功能设置相关
C-a r|C-r (wrap) 是否设置automatic margins
C-a C-v (digraph) 设置digraph
C-a W (width) 设置列宽80/132
C-a f|C-f (flow) 设置flow on, off or auto.
C-a C-g (vbell) 切换到虚拟响铃模式(vbell)
#清屏,锁屏,挂起
C-a x|C-x (lockscreen) 锁屏,锁住当前window,需用户密码解锁
C-a z|C-z (suspend) 挂起,把当前session放到后台执行,用shell的fg命令恢复到前台
C-a C (clear) 清屏
C-a l|C-l (redisplay) 刷新当前window
C-a Z (reset) 重置环境变量到screen开启时的最初状态
C-a {|} (history) 复制并粘贴上一次命令行,类似bash命令行的C-p
#复制粘贴模式相关
C-a [|C-[|esc (copy) 进入到copy/scrollback模式,可以复制,回滚和搜索,命令模式与vi相同
C-a esc|] (paste .) 粘贴buffer
C-a = (removebuf) 删除buffer
C-a < (readbuf) 从文件中读取buffer
C-a > (writebuf) 将buffer写入文件
#monitor功能
C-a _ (silence) 开启或关闭monitoring
C-a M (monitor) 是否将当前window设置为monitored
#login相关
C-a I (login on) 开启login
C-a O (login off) 关闭login
C-a L (login) 切换当前window到login
#写入文件相关
C-a h (hardcopy) 将当前window的快照写入到当前目录的"hardcopy.n".
C-a H (log) 将当前window的日志记录到当前目录的"screenlog.n".
C-a . (dumptermcap) 写入".termcap"
###################################################################
#########
常见用法:
#########
*******
启动:
*******
1.直接在命令行键入screen命令
screen
直接敲入命令screen会创建一个跑着shell的screen session。在这个session里,你所做的一切操作和实际shell里的操作完全一样,最多可能在键值上有些许的交叉,但几乎不会有什么影响。 键入exit可以退出该window,如果这是该screen session的唯一window,则该screen session退出,否则screen自动切换到前一个window。
2.Screen命令后接要执行的程序。
screen ranger #screen创建一个执行ranger的单窗口会话,退出ranger也将退出该窗口/会话。
screen mplayer -vo fbdev2 -zoom -x 1024 -y 768 foo.rmvb #screen创建一个执行mplayer的单窗口,同样,退出ranger也将退出该窗口/会话。
3.以上两种方式都创建新的screen会话。
我们还可以在一个已有screen session中创建新的window。在当前screen窗口中键入C-a c,即Ctrl键+a键,之后再按下c键,screen 在该会话内生成一个新的window并切换到该window。同时,screen可以在不中断screen窗口中程序的运行而暂时断开 (detach)screen会话,并在随后时间重新连接(attach)该会话,重新控制各窗口中运行的程序。
而给screen发送命令使用了特殊的键组合C-a。这是因为键盘上键入的信息是直接发送给shell,所以必须用其他方式向screen窗口管理器发 出命令,默认情况下,screen接收以C-a开始的命令。这种命令形式在screen中叫做键绑定(key binding),C-a叫做命令字符(command character)。
通过C-a d暂时中断刚创建的session(回到进入screen前的shell环境),然后再敲入screen则可再创建一个新的screen session。这样,你可以建立多个session,再建立多个window来满足系统管理的多窗口需求,比起Ctrl+Alt+F1...F7这样在 多个控制台切换来得方便实用且高效,当然,比"nohup [argument…] &"(虽然nohup很容易使用,但还是比较“简陋”的,对于简单的命令能够应付过来,对于复杂的需要人机交互的任务就麻烦了) 也更实际得多。此外,即使从系统中注销原来在screen session中的程序或进程也仍在继续运行,真的是相当方便咧。
在shell(没有进入screen之前)环境下,可以通过:
screen -d #detach某个session
screen -ls #查看所有的screen sessions
screen -r #进入sessionid所指定screen session
exit #关闭当前window,并且切换到下一个window(当退出最后一个window时,该终端自动终止,并且退回到原始shell状态)
*************
分割窗口
*************
GNU screen默认提供了一个水平(横向)分割窗口的功能,目前还不支持垂直(纵向)分割,这一点上,以BSD协议发布的tmux就更胜一筹,详情请参阅tmux篇。
按下Ctrl-A再按一下S(大写的S)就会看到屏幕被水平等分成两部分,可以通过C-A Tab来再分割的窗口间跳转。
调整窗口尺寸,可以在命令行模式进行调整,如:
resize +N #增加当前分割窗口N行
resize -N #减少当前分割窗口N行
resize N #指定当前分割窗口为N行
resize = #让所有的window一样高
resize max #让当前的window扩大到最高
resize min #让当前的window减少到最低
可以将键绑定写入到~/.screenrc中,如:
bind + resize +3
bind - resize -3
bind = resize =
bind m resize max
之后,通过source ~/.screenrc重新加载配置后便可以使用新的键绑定来调整窗口大小了!
C-a + 扩大当前窗口,增加3行
C-a - 缩小当前窗口,减小3行
C-a F (fit) 将所有window的尺寸调整到同当前window一样
当然,这样设置与某些键绑定重复,但不影响使用,如果喜欢这个功能可以牺牲某些用之甚少的功能么!呵呵!
设置后以~/.screenrc中的键绑定为主,有兴趣的朋友可以多试试!
****************
转义控制符
****************
screen默认把C-a看作是screen命令的开始,所以如果想要screen窗口接收到C-a字符(C-a在shell环境下默认跳到命令行的开头),就要输入C-a a。
screen也允许使用-e选项自定义命令字符和转义字符,其格式为:
-exy x为命令字符,y为转义命令字符的字符,如:
screen -e^tt #指定命令字符为C-t,转义C-t的字符为t
当然,这只是临时性的修改了命令字,待系统重启后则又恢复到默认状态,那么有没有一种方法可以永久性地修改并保存命令字呢!答案是肯定的,可以编辑~/.screenrc或全局文件/etc/screenrc,建议修改用户各自的自定义文件~/.screenrc,增加以下选项即可。
escape ^Tt #定义screen的功能键为Ctrl-T
思考:有的朋友肯定会问,为什么要设置为Ctrl-T呢?其它键绑定不行吗?
问的好,确实,键值可以依个人喜好任意设置,但我们知道,unix-like系统的快捷键多如牛毛,很多键都是shell默认的绑定键,所以找个空缺的键还真的比较困难,但我们可以根据击键方便度和使用频率来加以取舍, 个人觉得,Ctrl-T是个不错的建议,因为,在shell(bash)下,Ctrl-T是交换相邻两个字符的位置,Ctrl-A是跳到命令行的开头,从 使用频率来看,Ctrl-A用的频繁得多,而当命令字设为Ctrl-T后,需要交换字符的位置时,按下Ctrl-T t也可以达到字符交换位置的效果。
**************
Copy模式
**************
C-a [ 可以进入copy模式,此模式的快捷键与vi相同,如:
C-b Backward,PageUp 向上翻一页
C-f Forward,PageDown 向下翻一页
C-d Backward,Half PageUp 向上翻半页
C-u Forward,Half PageDown 向下翻半页
H Head 屏暮的顶部
M Middle 屏幕的中间
L Last 屏幕的底部
gg 整个缓冲区的第一行
ng 整个缓冲区的第几行,n为行数,如:第3行则为,3g
G 整个缓冲区的最后一行
0 行首
$ 行末
w 以词为单位向前移动到下一个词的开头
e 以词为单位向前移动到下一个词的结尾
b 以词为单位向后移动到上一个词的开头
W 以空格为单位向前移动到下一个词的开头
E 以空格为单位向前移动到下一个词的结尾
B 以空格为单位向后移动到上一个词的开头
Space第一次按为标记区域的起点,第二次按为终点(回车也可以),这样,起点和终点间的字符即为所复制的部分。
粘贴所复制的区域
Esc 退出copy mode
注:copy模式的更多的快捷键请自行参考vi
*********************
多session实例:
*********************
通过ps -e|grep screen我们可以看到,
7153 ? 00:00:02 screen
7391 pts/8 00:00:00 screen
7392 ? 00:00:00 screen
7615 pts/1 00:00:00 screen
目前有4个screen进程在运行
现在我开启了3个session,其中有两个(liujun,ubuntu)是Detached状态,一个(test)是Attached状态。
liujun@ubuntu:~$screen -ls
There are screens on:
7415.liujun (2012年06月10日 19时52分00秒) (Detached)
7392.test (2012年06月10日 19时51分30秒) (Attached)
7153.pts-1.ubuntu (2012年06月10日 18时12分50秒) (Detached)
3 Sockets in /var/run/screen/S-liujun.
当我们想恢复某个session且只开启了一个session时,只需要键入screen -r即可恢复。而当有多个session时,系统将提示选择一个
如:对于"test"这个session是不能够通过screen -r 7392来恢复的,因为它本来就没有detach,所以根本无需recover,当我们要恢复ubuntu这个session时我们可以这样:
screen -r 7153
如果由于某种原因其中一个session死掉了(例如人为杀掉该会话),这时screen -li会显示该会话为dead状态。可以使用screen -wipe命令清除该session:
screen -wipe
"-d –m" 选项是一对很有意思的搭档。因为他们启动的是一个开始就处于断开模式的会话。你可以在随后需要的时候连接上该会话。有时候这是一个很有用的功能,比如我们可以使用它调试后台程序。
该选项一个更常用的搭配是:-dmS sessionname
screen -dmS ubuntu test xiao #这样就启动了3个一开始就处于离线状态的session
screen -r ubuntu #连接(恢复)该会话
****************
重命名窗口
****************
通常我们在使用过程中都会开启好多个window,而当按下C-a w查询window列表时,给出来
1$ bash 2-$ bash 3*$ bash
少还好,一旦超过5个,哇,那真的是有些头晕,毕竟每个都叫bash切换时总会时不时的打搅,很影响心情的。所有我每次都会重命名几个window,这样既方便记忆又方便切换,真的是不错的功能噢!
C-a A(大写A)可以轻松地(根据自己的喜好或window功能)进行重命名。如:我常用这几个,哈,什么意缊这里就不多作阐释了,自己心里有数就行!呵呵,
1*$ ubuntu 2$ xiao 3-$ hello
*********************
指定session名
*********************
缺省情况下screen使用PID.TTY.HOST的命名规则,太多的session,很可能太多的PID让你眼花缭乱,所以指定一个好记的名字,就显得重要起来
screen -S ubuntu #可开启一个名叫ubuntu的session
screen -dmS ubuntu #可开启一个名叫ubuntu的且初始状态是断开状态的session
*******************
管理远程会话
*******************
使用ssh等远程连接linux服务器工作的时候,比如需要编译某些程序而这时网络不稳定断线,工作就白干了,又的重新连接重复刚才的工作,这时候screen就可以派上用场了。
只要别杀掉screen会话, 把多窗口的管理任务放心地交给screen吧,screen一定不会让你失望,screen能帮你“保存”你想继续运行的任务,并在你需要恢复的时候随时待命,怎么样,是不是相当方便呢!
你需要做的只是打开一个terminal(或Putty)通过ssh(telnet,rsh等)登录主机,再键入screen创建需要的screen session,退出的时候C-a d“保存”你的工作,下次登录后直接screen -r 就可以了。
当然,最好能给每个窗口起一个名字。使用C-a A给window起名,使用C-a w查看window列表。
****************************
同步显示与操作功能
****************************
1.当几个分割的窗口处于同一window时,则输出是完全一模一样,完全同步。比如:水平分割的两个窗口,上面一个是bash1,下面一个也是bash1的话,那么这两个分割的窗口将保持同步,有点像金山打字通的感觉,呵呵!
2.screen 给我们提供了一个"-x"选项,这个选项可相当神奇噢!这也是所谓的“多重显示模式”,即在同一个session下能在不同的终端显示并共同控制窗口动作。
简单讲,她不仅能同步显示你的屏幕给另一个会话(有点类似于文本界面下远程协助或桌面噢!),而且同时联机的两个终端都能对该window进行控制操作。 这在帮别人处理问题可是一个相当好用的功能咧,因为这样既可以让对方同步看到你的操作,也可以实地检验对方的操作,就像实地演示手把手交一样,省下很多后 续解释工作呢!
方法:
a.双方同时登陆linux主机 #同一个session多个用户同时attach
b.一方(演示方)运行:
screen -S test #开启一个session,我这时命名为test
mocp test.m3u #用mocp播放mp3
c.一方(观看方)运行:
screen -x test #通过multi display mode来attach同一个会话
怎么样,是不是两边都能同时显示并同时操控呢!很好玩呢,赶快尝试一下吧!
**********************
强大的可定制性
**********************
GNU screen为我们提供了丰富强大的定制功能。
你可以在screen的默认两级配置文件/etc/screenrc和$HOME/.screenrc中指定更多的个性化设置。包括设定screen选 项,定制绑定键,设定screen会话自启动窗口,启用多用户模式,定制用户访问权限控制等等。如果你愿意的话,也可以自己指定screen配置文件。
例如:以多用户功能为例,screen默认是以单用户模式运行的,你需要在配置文件中指 定 multiuser on 来打开多用户模式,通过acl*(acladd,acldel,aclchg...)命令,你可以灵活配置其他用户访问你的screen会话。更多配置文 件内容请参考screen的man页。
startup_message off #启动时不显示欢迎屏幕
escape ^Tt #定义screen的功能键为Ctrl-T
defscrollback 1024 #屏幕缓冲区1024行
vbell on|off #关闭错误提示
vbell_msg "Wuff--Wuff!" #错误提示消息文字
bind w windowlist #按C-a w或C-a C-w显示窗口列表
defflow on # 强制screen去接收^S^Q信号
hardstatus off # 关闭hardstatus
hardstatus string "%h%? users: %u%?" #设置hardstatus字符串
hardstatus onhardstatus alwayslastlinehardstatus string "%{.bW}%-w%{.rY}%n %t%{-}%+w %=%{..G} %H(%l) %{..Y} %Y/%m/%d %c:%s " #在最下一行显示窗口列表和时钟
hardstatus lastline "%-Lw%{= BW}P>%n%f* %t%{-}%+Lw%<" #在屏幕的底部列出所有window的名称并以蓝色高亮显示当前window
termcapinfo xterm*|rxvt*|kterm*|Eterm* hs:ts=\E]0;:fs=\007:ds=\E]0;\007 #在gui终端界面中设置hardstatus的标题和图标
*************
参考资料
*************
* “Advanced Programming in the UNIX® Environment: Second Edition” W. Richard Stevens, Stephen A. Rago 提供了更多关于Linux/Unix进程关系、信号的知识。
* GNU Screen的官方网站:
http://www.gnu.org/software/screen/
* Screen的man page提供了最详细的信息:
http://www.slac.stanford.edu/com ... nsole/screen.1.html
*
http://hi.baidu.com/phps/blog/item/790973c6c29c8d159c163d0c.html
转载于:https://www.cnblogs.com/lixuebin/archive/2013/05/07/10814676.html