多路复用终端管理器screen

GNU Screen是一个终端多路复用管理器,用于同时并发的多路虚拟控制台,允许用在一个登录会话中访问分隔的会话,或者断开并重连一个终端的会话。这样,用户远程登录到服务器,即使关闭终端,也可以再次登录服务器访问上次断开的终端。

独立编译安装screen

GNU Screen官网 下载源代码可以自己编译安装最新版本,编译以后生成的screen可执行程序可以直接使用。

不过,启动这个自己编译的screen显示连接的sockets目录可能和发行版自带的screen所设置的SockDir不同,则可能看不到之前的保持的会话。解决方法参考 How do I reattach to a screen session when the socket is there, but screen won't use it? 也就是通过设置 SCREENDIR 环境变量来实现

export SCREENDIR="/var/run/screen"

不过,我遇到升级到screen 4.06 版本无法访问 4.03 的sockets的问题。

screen使用tips

screen窗口

Ctrl-a,然后在当前窗口中按双引号键("),就可以看到会话中可用窗口的列表

终止当前窗口的方法是,在窗口的 shell 提示上输入 exit,或者按键盘快捷键 Ctrl-a,然后按 k(小写的字母 K,代表 “kill”)。如果使用后一种方法,那么在窗口底部会出现一个警告,要求您确认要杀死此窗口。按 y(小写的字母 Y,代表 “yes”)确认,或按 n(小写的字母 N,代表 “no”)拒绝。

  • 指定窗口名称

指定窗口名称的方法:激活窗口,按 Ctrl-a A(大写的字母 A,代表 “Annotate”),根据需要按 Backspace 删除现有的名称,然后在提示上输入一个有意义的名称

  • 修改窗口编号

由于screen支持0~9的10个快捷窗口切换,所以窗口编号非常重要。如果有部分窗口关闭,空出了0~9之间的编号,则可以修改其他窗口来填补这个编号。

修改方法:激活窗口,按 Ctrl-a,然后输入:number xx就是新窗口编号数字)

  • 修改窗口顺序

如果要重排窗口顺序,按下Ctrl-a,然后输入:windowlist。此时在显示的窗口列表中,使用.将窗口下移,使用,将窗口上移。

screen复制和粘贴

参考 How to copy the GNU Screen copy buffer to the clipboard?

  • 进入screen的复制模式: Ctrl-a,然后按下[

  • 此时可以通过类似vi的方式进行光标移动

  • 在需要复制的行,按下space空格按键,表示选择。然后再按下j或者k上下移动光标,复制需要复制的所有行

  • 再次按下space空格按键,结束复制。此时两次space按键之间的所有行都被复制到缓存中

  • 粘贴命令是 Ctrl-a,然后按下],内容复制到当前位置

screen配置

可以使用状态栏在视觉上进一步区分各个窗口 : 主目录中创建包含以下代码的 .screenrc 文件

hardstatus on
hardstatus alwayslastline
hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a "
  • .screenrc配置案例一(推荐):

source /etc/screenrc
altscreen off
hardstatus none
caption always "%{= wk}%{wk}%-Lw%{rw} %n+%f %t %{wk}%+Lw %=%c%{= R}%{-}"

shelltitle "$ |bash"
defscrollback 50000
startup_message off
escape ^aa

termcapinfo xterm|xterms|xs|rxvt ti@:te@ # scroll bar support
term rxvt # mouse support

bindkey -k k; screen
bindkey -k F1 prev
bindkey -k F2 next
bindkey -d -k kb stuff ^H
bind x remove
bind j eval "focus down"
bind k eval "focus up"
bind s eval "split" "focus down" "prev"
vbell off
shell -bash
  • .screenrc配置案例二:

# GNU Screen - main configuration file
# All other .screenrc files will source this file to inherit settings.
# Author: Christian Wills - cwills.sys@gmail.com

# Allow bold colors - necessary for some reason
attrcolor b ".I"

# Tell screen how to set colors. AB = background, AF=foreground
termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'

# Enables use of shift-PgUp and shift-PgDn
termcapinfo xterm|xterms|xs|rxvt ti@:te@

# Erase background with current bg color
defbce "on"

# Enable 256 color term
term xterm-256color

# Cache 30000 lines for scroll back
defscrollback 30000

# New mail notification
backtick 101 30 15 $HOME/bin/mailstatus.sh

hardstatus alwayslastline
# Very nice tabbed colored hardstatus line
hardstatus string '%{= Kd} %{= Kd}%-w%{= Kr}[%{= KW}%n %t%{= Kr}]%{= Kd}%+w %-= %{KG} %H%{KW}|%{KY}%101`%{KW}|%D %M %d %Y%{= Kc} %C%A%{-}'

# change command character from ctrl-a to ctrl-b (emacs users may want this)
#escape ^Bb

# Hide hardstatus: ctrl-a f
bind f eval "hardstatus ignore"
# Show hardstatus: ctrl-a F
bind F eval "hardstatus alwayslastline"

A nice default screenrc 也有一个类似推荐配置。What are useful .screenrc settings?推荐了byobu(屏风)作为screen或者tmux(默认,如果安装了tmux的话)的wrap工具,提供了非常友好的交互方法。

screen快捷键

  • 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 [ 进入拷贝/回滚模式

KeyActionNotes

Ctrl+a c

new window

Ctrl+a n

next window

Ctrl+a p

previous window

Ctrl+a "

select window from list

Ctrl+a Ctrl+a

previous window viewed

Ctrl+a S

split terminal horizontally into regions Ctrl+a c to create new window there

Ctrl+a

split terminal vertically into regions Requires screen >= 4.1

Ctrl+a :resize

resize region

Ctrl+a :fit

fit screen size to new terminal size Ctrl+a F is the same. Do after resizing xterm

Ctrl+a :remove

remove region Ctrl+a X is the same

Ctrl+a tab

Move to next region

Ctrl+a d

detach screen from terminal Start screen with -r option to reattach

Ctrl+a A

set window title

Ctrl+a x

lock session Enter user password to unlock

Ctrl+a [

enter scrollback/copy mode Enter to start and end copy region. Ctrl+a ] to leave this mode

Ctrl+a ]

paste buffer Supports pasting between windows

Ctrl+a >

write paste buffer to file useful for copying between screens

Ctrl+a <

read paste buffer from file useful for pasting between screens

Ctrl+a ?

show key bindings/command names Note unbound commands only in man page

Ctrl+a :

goto screen command prompt up shows last command entered

screen常用命令

screen -t name 命令在创建窗口时指定窗口名称

screen -L 命令把每个窗口的输出记录在日志中。每个窗口有自己的日志文件,文件名通常是 ~/screenlog.n,其中的 n 是窗口列表中显示的窗口编号。(这个-L参数不需要指定文件名)

最有用的组合键包括:按 Ctrl-a,然后按 0(数字零)到 9 立即切换到特定的窗口;按 Ctrl-a,然后按 C(大写的字母 C,代表 “Clear”)清除一个窗口的内容;按 Ctrl-a,然后按 H 启用或禁用日志记录;按 Ctrl-a,然后按 Ctrl-a 在当前窗口和前一个窗口之间来回切换;按 Ctrl-a,然后按 Ctrl-\(反斜杠)杀死所有窗口并终止当前的 Screen 会话

Screen 会话的连接,可以用 screen -p ID 命令重新连接特定的窗口,其中的 ID 是一个数字或名称

screen -r -p ghost

多用户模式连接其它窗口

screen -x -r sharing -p one

这里 -x 表示多用户模式,-p one表示连接到另外一个名字叫one的窗口,这样两个窗口就连接在一起,并且可以看到共同的输入输出。

屏幕分隔

左右分割屏幕快捷键是Ctrl-a |,上下分割屏幕快捷键是Ctro-a S

去除split出来的region使用快捷键Ctrl-a X

分屏以后,可以使用Ctrl-a <tab>在各个区块间切换,不过,分割屏幕之后,切换到新的屏幕,需要使用Ctrl-a c来创建会话。

C/P模式和操作

使用快捷键Ctrl-a <Esc>或者Ctrl-a [可以进入copy/paste模式,这个模式下可以像在vi中一样移动光标,并可以使用空格键设置标记。其实在这个模式下有很多类似vi的操作,譬如使用/进行搜索,使用y快速标记一行,使用w快速标记一个单词等。关于C/P模式下的高级操作,其文档的这一部分有比较详细的说明。

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

ssh远程后台在screen中执行脚本

这个功能是screen的杀手锏,提供了远程在后台执行脚本的能力。并且可以随时连接到screen进行维护

参考how to run a command in background using ssh and detach the session

screen -S restart_network -dm /etc/init.d/network restart

这样 -dm 命令可以执行shell时断开,以便后续再连接访问。

	   -d|-D [pid.tty.host]
            does not start screen, but detaches the elsewhere running screen session. It has the same  effect  as  typing
            "C-a  d" from screen’s controlling terminal. -D is the equivalent to the power detach key.  If no session can
            be detached, this option is ignored. In combination with the  -r/-R  option  more  powerful  effects  can  be
            achieved:	        
		-m   causes screen to ignore the $STY environment variable.  With  "screen  -m"  creation  of  a  new  session  is
            enforced, regardless whether screen is called from within another screen session or not. This flag has a spe-
            cial meaning in connection with the ‘-d’ option:        
		-d -m   Start screen in "detached" mode. This creates a new session but doesn’t attach to it. This is  useful  for
        system startup scripts.

使用screen的好处是某些需要使用tty的工具可以正常执行

注意一定要正常能够执行的shell脚本,否则会直接结束,并且返回值还是0,就不知道是否正确执行脚本了

使用nohup也可以实现

ssh remoteserver 'nohup /path/to/script `</dev/null` >nohup.out 2>&1 &'

但是nohup方式不利于再次连接终端进行检查。

一个案例:需要在服务器上通过strace工具来跟踪程序example_program

pssh -ih nc_list 'screen -S strace_example_program -d -m sudo strace -o example_program.strace -p `pgrep example_program`'

Cannot open your terminal

当时用sudo切换到普通用户身份执行screen指令时,会遇到报错

Cannot open your terminal '/dev/pts/135' - please check.

这个报错原因是因为你通过其他用户身份登录到系统终端中,然后执行了sudo su指令,此时tty终端设备并没有随着身份切换而改变,所以切换身份后用户无法访问终端设备文件。

用以下方法可以验证:

  • 首先登录到系统中,执行tty命令可以查看到终端设备名:

#tty
/dev/pts/135
  • 然后切换身份到admin用户再次执行tty命令则看到终端设备名不变,依然是/dev/pts/135

#su - admin
-bash: ulimit: open files: cannot modify limit: Operation not permitted

$tty
/dev/pts/135

解决方法有以下几种:

  • 退出系统,直接用需要使用screen指令的用户身份登录系统,这样使用screen命令就不会有无法访问/dev/pts/XXX权限问题

  • 直接修改设备权限,例如chmod 777 /dev/pts/135,但是这个方法存在安全隐患,不建议使用

  • 推荐的解决方法:使用script /dev/null指令,这样用户的tty设备就会切换到其他终端设备。

案例:

$script /dev/null
Script started, file is /dev/null
bash: ulimit: open files: cannot modify limit: Operation not permitted

$tty
/dev/pts/189

此时使用screen指令就不会存在权限错误问题。

参考

Last updated