Xiaopei's DokuWiki

These are the good times in your life,
so put on a smile and it'll be alright

User Tools

Site Tools


it:linux:screen

screen

背景知识

SIGHUP 信号, that's why 关掉窗口/断开连接会使得正在运行的程序死掉.

在Linux/Unix中,有这样几个概念:

  • 进程组(process group):一个或多个进程的集合,每一个进程组有唯一一个进程组ID,即进程组长进程的ID。
  • 会话期(session):一个或多个进程组的集合,有唯一一个会话期首进程(session leader)。会话期ID为首进程的ID。
  • 会话期可以有一个单独的控制终端(controlling terminal)。与控制终端连接的会话期首进程叫做控制进程(controlling process)。当前与终端交互的进程称为前台进程组。其余进程组称为后台进程组。

根据POSIX.1定义:

  • 挂断信号(SIGHUP)默认的动作是终止程序。
  • 当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)。
  • 如果会话期首进程终止,则该信号发送到该会话期前台进程组。
  • 一个进程退出导致一个孤儿进程组中产生时,如果任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中所有进程。

因此当网络断开或终端窗口关闭后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出。

nohup

如果我们可以忽略SIGHUP信号,关掉窗口应该就不会影响程序的运行了。nohup命令可以达到这个目的,如果程序的标准输出/标准错误是终端,nohup默认将其重定向到nohup.out文件。值得注意的是nohup命令只是使得程序忽略SIGHUP信号,还需要使用标记&把它放在后台运行。

nohup <command> [argument…] &

虽然nohup很容易使用,但还是比较“简陋”的,对于简单的命令能够应付过来,对于复杂的需要人机交互的任务就麻烦了。

回到 screen

简单来说,Screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。Screen中有会话的概念,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。

初探

  • 创建新 screen
#1
$ screen
 
#2
$ screen vi foo
# 退出vi将退出该 screen
  • 暂时中断会话

在 screen 窗口内 C-a d

  • 列表 screen
$ screen -ls
  • 重新连接
$ screen -r 16582

常用的键绑定

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 [进入拷贝/回滚模式
C-a S新建一个水平的分屏1)
C-a <tab>在分屏之间切换
C-a Q关闭当前活跃分屏外的所有分屏

常用的命令选项

-c file使用配置文件file,而不使用默认的$HOME/.screenrc
-d or -D [pid.tty.host]不开启新的screen会话,而是断开其他正在运行的screen会话
-h num指定历史回滚缓冲区大小为num行
-list or -ls列出现有screen会话,格式为pid.tty.host
-d -m启动一个开始就处于断开模式的会话
-r sessionowner/ [pid.tty.host]重新连接一个断开的会话。多用户模式下连接到其他用户screen会话需要指定sessionowner,需要setuid-root权限
-S sessionname创建screen会话时为会话指定一个名字
-v显示screen版本信息
-wipe [match]同-list,但删掉那些无法连接的会话

-d –m 选项是一对很有意思的搭档。他们启动一个开始就处于断开模式的会话。你可以在随后需要的时候连接上该会话。有时候这是一个很有用的功能,比如我们可以使用它调试后台程序。该选项一个更常用的搭配是:-dmS sessionname

$ screen -d -m tailf /var/log/php5/cgi.log

管理你的远程会话

你是不是每次登录到系统都要开很多窗口,然后每天都要重复打开关闭这些窗口?让screen来帮你“保存”吧,你只需要打开一个ssh窗口,创建需要的screen窗口,退出的时候C-a d“保存”你的工作,只要别杀掉screen会话,下次登录后直接screen -r <screen_pid>就可以了。

最好能给每个窗口起一个名字,这样好记些。使用C-a A给窗口起名字。使用C-a w可以看到这些窗口名字。

screen 的进程

# 开启 screen
toksea@ubuntu:~$ screen
# 在 screen 中再建立一个会话
C-a c
# 查看进程
toksea@ubuntu:~$ pstree
     ├─sshd───sshd───sshd───bash───screen───screen─┬─bash
     |                                             └─bash───pstree

我的配置

.screenrc
# 显示 tab bar
caption always "%{= kw}%-w%{= BW}%n %t%{-}%+w %-= @%H - %LD %d %LM - %c"
 
# 重设 Escape Key
escape ^A^A
bind o other
# 使用鼠标滚轮
termcapinfo xterm* ti@:te@

tmux

scroll 问题

tmux 默认不能用滚轮查看之前的输出… wtf

http://superuser.com/questions/209437/how-do-i-scroll-in-tmux

tmux 的进程

# 开启 tmux
toksea@ubuntu:~$ tmux 
# 在 tmux 中再建立一个会话
C-b c
# 查看进程
toksea@ubuntu:~$ pstree
     ├─sshd───sshd───sshd───bash───tmux
     ├─tmux─┬─bash
     │      └─bash───pstree

refs

1)
新建的分屏默认啥都没有,用 C-a <tab> 切换过去后 C-a c 新建shell
it/linux/screen.txt · Last modified: 2014/11/12 16:34 by admin