如何在Linux VPS上使用GNU Screen
从安装到日常使用,全面学习GNU Screen。管理会话、分割区域、配置.screenrc,在Debian 12和Ubuntu 24.04上保持SSH断开后进程持续运行。
如何在Linux VPS上使用GNU Screen
你通过SSH连接到服务器,启动一个长时间运行的进程,然后连接断了。进程随之终止。GNU Screen解决了这个问题。它运行的终端会话独立于SSH连接而存在。你可以分离会话、断开连接,几个小时后重新连接,然后从中断的地方继续。
本教程涵盖GNU Screen从安装到日常工作流的全部内容,适用于Debian 12和Ubuntu 24.04。你将学习会话管理、窗口操作、分割区域、复制模式以及.screenrc自定义配置。
什么是GNU Screen?
GNU Screen是一个终端复用器(terminal multiplexer)。它创建运行在服务器上的虚拟终端会话,独立于你的SSH连接。在一个Screen会话中,你可以打开多个窗口、将终端分割为多个区域,并回滚查看历史输出。
Screen位于SSH客户端和Shell之间。当你从Screen会话分离时,其中运行的所有程序继续执行。重新连接后,你看到的是相同的输出、相同的运行进程、相同的状态。这使它成为远程VPS工作中不可或缺的工具——SSH连接随时可能意外断开。
Screen自1987年起就已存在,所有主流Linux发行版的默认软件仓库中都包含它。当前版本为Debian 12上的4.9.0和Ubuntu 24.04上的4.9.1。
如何在Debian和Ubuntu上安装GNU Screen?
Screen在Debian 12和Ubuntu 24.04的默认软件仓库中都可用。一条apt命令即可完成安装。大多数精简VPS镜像中并未预装Screen。
更新软件包索引并安装Screen:
sudo apt update && sudo apt install -y screen
验证安装:
screen --version
在Debian 12上,你会看到:
Screen version 4.09.00 (GNU) 30-Jan-21
在Ubuntu 24.04上:
Screen version 4.09.01 (GNU) 20-Aug-23
如果显示了版本号,说明Screen已可以使用。
如何启动和命名Screen会话?
运行screen即可启动新的Screen会话。但不指定名称会导致后续难以识别。始终使用-S参数为会话命名。
启动命名会话:
screen -S myproject
终端清屏,你现在已经进入Screen会话。此处运行的一切都会在SSH连接断开后继续存在。
验证你是否在Screen会话中:
echo $STY
这会输出会话名称。如果显示类似12345.myproject的内容,你就在Screen内。如果没有输出,说明你不在会话中。
Screen命令参考
所有Screen命令都以前缀键Ctrl-a开头,后跟另一个键。这个前缀被称为"转义字符"(escape character)。
| 快捷键 | 操作 | 说明 |
|---|---|---|
Ctrl-a d |
分离会话 | 会话继续运行 |
Ctrl-a c |
创建新窗口 | 打开新的Shell |
Ctrl-a n |
下一个窗口 | 向前循环 |
Ctrl-a p |
上一个窗口 | 向后循环 |
Ctrl-a " |
列出所有窗口 | 用方向键选择 |
Ctrl-a A |
重命名当前窗口 | 输入新名称后按Enter |
Ctrl-a k |
关闭当前窗口 | 需要确认 |
Ctrl-a S |
水平分割 | 大写S |
Ctrl-a | |
垂直分割 | 管道符 |
Ctrl-a Tab |
在区域间切换 | 循环切换各分割区域 |
Ctrl-a X |
关闭当前区域 | 大写X |
Ctrl-a [ |
进入复制模式 | 也可用Ctrl-a Esc |
Ctrl-a ] |
粘贴已复制的文本 | 从缓冲区粘贴 |
Ctrl-a ? |
显示快捷键绑定 | 内置帮助 |
如何分离和重新连接Screen会话?
这是核心工作流。在Screen中启动一个进程,分离会话,进程继续运行。之后重新连接来检查进度。
分离当前会话:
按Ctrl-a然后按d。
你会看到:
[detached from 12345.myproject]
会话现在在后台运行。你可以安全地关闭SSH连接。
列出所有会话:
screen -ls
输出:
There are screens on:
12345.myproject (03/19/2026 02:15:30 PM) (Detached)
1 Sockets in /run/screen/S-your_user.
重新连接到会话:
screen -r myproject
你回到了会话中,所有输出和进程完好无损。
如果只有一个已分离的会话,不带名称直接运行screen -r也可以。
会话显示为已连接但你并未连接时怎么办?
有时会话显示为(Attached),即使你并未连接。这发生在SSH非正常断开时。Screen仍然认为旧连接是活跃的。
根据以下决策表选择正确的参数:
| 场景 | 命令 | 作用 |
|---|---|---|
| 会话显示"Attached"但你并未连接 | screen -D -r myproject |
强制分离旧连接,然后在此处重新连接 |
| 会话显示"Attached"且你想共享 | screen -x myproject |
不分离另一端直接连接(多显示模式) |
| 会话显示"Attached",你想接管 | screen -d -r myproject |
分离远端,在本地重新连接 |
最常见的情况是使用screen -D -r。它可以处理SSH崩溃后的残留连接。
重新连接后验证会话状态:
screen -ls
会话现在应显示为(Attached)。
如何在SSH断开后保持进程运行?
启动Screen会话,在其中运行进程,然后分离。进程可以在SSH断开、网络中断甚至关闭笔记本电脑的情况下继续运行。
完整工作流如下:
screen -S training
在会话中启动你的长时间运行进程:
python3 train_model.py --epochs 100
按Ctrl-a d分离。你会看到:
[detached from 12345.training]
关闭SSH。去喝杯咖啡。稍后回来:
ssh user@your-server
screen -r training
你的训练任务仍在运行,你可以看到离开期间产生的所有输出。
如何在Screen中管理多个窗口?
一个Screen会话可以包含多个窗口。每个窗口是一个独立的Shell。可以把窗口理解为浏览器中的标签页。
在会话中创建新窗口:
按Ctrl-a c。
新的Shell打开了。你之前的窗口仍然存在。在窗口间切换:
Ctrl-a n切换到下一个窗口Ctrl-a p切换到上一个窗口Ctrl-a 0到Ctrl-a 9按编号跳转到指定窗口Ctrl-a "显示所有窗口列表。用方向键选择后按Enter。
重命名当前窗口以便识别:
按Ctrl-a A,输入名称,然后按Enter。
查看当前所在窗口:
按Ctrl-a "查看窗口列表。当前窗口带有星号标记。
关闭窗口可以在其Shell中输入exit,或者按Ctrl-a k然后输入y确认。
如何将终端分割为多个区域?
Screen可以将终端分割为多个区域,每个区域显示不同的窗口。这在一个窗格监控日志、另一个窗格工作时非常有用。
逐步构建监控布局
我们来构建一个三窗格布局:上方是主Shell,左下方是日志,右下方是系统监控。
第1步: 启动命名会话:
screen -S monitor
第2步: 水平分割。按Ctrl-a S(大写S)。
终端分成了上下两个区域。光标停留在上方区域。
第3步: 移动到下方区域。按Ctrl-a Tab。
下方区域是空的。你需要为它分配一个窗口。
第4步: 在下方区域创建新窗口。按Ctrl-a c。
现在下方区域有了一个Shell。
第5步: 垂直分割下方区域。按Ctrl-a |(管道符)。
下半部分现在有了左右两个区域。按Ctrl-a Tab移动到右侧新区域。
第6步: 创建另一个窗口。按Ctrl-a c。
第7步: 启动监控工具。使用Ctrl-a Tab在区域间导航:
- 上方区域:主工作Shell
- 左下方:运行
tail -f /var/log/syslog - 右下方:运行
htop
区域管理命令
| 快捷键 | 操作 |
|---|---|
Ctrl-a S |
水平分割 |
Ctrl-a | |
垂直分割 |
Ctrl-a Tab |
移动到下一个区域 |
Ctrl-a X |
关闭当前区域(窗口保持打开) |
Ctrl-a Q |
关闭当前区域外的所有区域 |
Ctrl-a :resize +5 |
将当前区域增大5行 |
Ctrl-a :resize -5 |
将当前区域缩小5行 |
需要注意:Screen在你分离时不会保存区域布局。重新连接后,所有分割都会消失,你只看到一个窗口。窗口本身(及其中的进程)会被保留。你需要手动重新分割。如果需要持久化的布局,可以在.screenrc中添加布局命令,或者考虑使用tmux——它在分离后会保留窗格布局。
如何使用复制模式和回滚缓冲区?
默认情况下,你无法在Screen会话中使用鼠标滚轮或Shift-PgUp向上滚动。Screen会捕获所有输入。要查看之前的输出,需要进入复制模式(copy mode)。
按Ctrl-a [或Ctrl-a Esc进入复制模式。
你现在处于类似vi的导航模式中:
| 按键 | 操作 |
|---|---|
| 方向键 | 移动光标 |
h/j/k/l |
移动光标(vi风格) |
Ctrl-u |
向上滚动半页 |
Ctrl-d |
向下滚动半页 |
0 |
行首 |
$ |
行尾 |
g |
跳到回滚缓冲区顶部 |
G |
跳到回滚缓冲区底部 |
/ |
向前搜索 |
? |
向后搜索 |
Space |
设置标记(选区起点/终点) |
Enter |
复制选中文本并退出复制模式 |
Esc |
不复制直接退出复制模式 |
复制文本的步骤:进入复制模式,移动到要复制的文本起始位置,按Space设置第一个标记,移动到末尾,再按Space。文本被复制到Screen的粘贴缓冲区中。
粘贴:按Ctrl-a ]。
默认的回滚缓冲区只有100行。这对于实际使用来说太少了。在.screenrc中增加它:
defscrollback 10000
这将每个窗口的回滚缓冲区设为10,000行。
如何通过.screenrc配置Screen?
Screen在启动时读取~/.screenrc。这个文件控制默认行为、快捷键绑定、状态栏和启动窗口。
好的.screenrc应该是什么样的?
以下是一份完整的.screenrc配置,每条指令都有说明:
# Disable the startup splash message
startup_message off
# Use bash as the default shell
shell /bin/bash
# Set scrollback buffer to 10,000 lines
defscrollback 10000
# Use 256-color terminal
term screen-256color
# Disable visual bell (use audible bell instead)
vbell off
# Enable alternate screen support (clears screen after less/vim exit)
altscreen on
# Status bar at the bottom of the screen
hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][ %=%{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][ %{B}%Y-%m-%d %{W}%c %{g}]'
# Detach on hangup (SSH disconnect)
autodetach on
# Don't block the whole session if a window goes unresponsive
nonblock on
# Log new screen windows in utmp
deflogin on
# Start window numbering at 1 instead of 0
bind c screen 1
bind ^c screen 1
bind 0 select 10
# Named windows at startup
screen -t shell 1
screen -t logs 2
screen -t work 3
创建此文件:
nano ~/.screenrc
粘贴上述配置并保存。
Hardstatus格式字符串详解
hardstatus行是.screenrc中功能最强(也最令人困惑)的部分。以下是示例中每个标记的含义:
| 标记 | 含义 |
|---|---|
%{= kG} |
设置颜色:黑色背景,亮绿色文字 |
%H |
系统主机名 |
%-Lw |
当前窗口之前的所有窗口 |
%{r}(%{W}%n*%f%t%{r}) |
当前窗口:红色括号,白色窗口编号+标志+标题 |
%+Lw |
当前窗口之后的所有窗口 |
%Y-%m-%d |
日期,格式为YYYY-MM-DD |
%c |
当前时间,格式为HH:MM |
颜色代码:k黑色、r红色、g绿色、y黄色、b蓝色、m品红色、c青色、w白色。大写字母表示高亮/粗体。
启动新会话查看状态栏:
screen -S test
你应该能看到底部的绿色状态栏,显示主机名、窗口列表和当前日期时间。
更改转义键
如果Ctrl-a与你的工作流冲突(它也是bash中"跳到行首"的快捷键),你可以重新绑定:
# Use Ctrl-j as the escape key instead of Ctrl-a
escape ^Jj
更改后,所有Screen命令使用Ctrl-j代替Ctrl-a。选一个你很少用到的键。
VPS上常见的GNU Screen工作流
保持部署进程运行
screen -S deploy
./deploy.sh --production
# Ctrl-a d to detach
稍后检查:
screen -r deploy
同时监控多个日志文件
screen -S logs
在会话内:
Ctrl-a S水平分割- 在上方区域:
tail -f /var/log/nginx/access.log Ctrl-a Tab移动到下方Ctrl-a c创建新窗口tail -f /var/log/nginx/error.log
运行长时间训练任务(AI开发者)
screen -S training
python3 -u train.py --model llama --epochs 50 2>&1 | tee training.log
# Ctrl-a d to detach
-u参数禁用Python输出缓冲,这样重新连接时可以实时看到输出。通过tee管道将输出同时保存到文件作为备份。
SSH断开后快速重新连接
如果在Screen中时SSH断开,只需重新连接:
ssh user@your-server
screen -D -r
screen -D -r会找到你的会话,强制分离残留连接,然后重新连接。
GNU Screen与tmux:应该选哪个?
Screen和tmux都是终端复用器。它们解决的是同一个核心问题。以下是客观比较:
| 特性 | GNU Screen | tmux |
|---|---|---|
| 首次发布 | 1987 | 2007 |
| 许可证 | GPL-3.0 | ISC(类BSD) |
| 开发活跃度 | 缓慢(5.0于2024年8月发布,此前多年不活跃) | 活跃(定期发布) |
| 窗格布局持久化 | 分离后丢失 | 分离后保留 |
| 默认前缀键 | Ctrl-a |
Ctrl-b |
| 配置文件 | .screenrc(自定义语法) |
.tmux.conf(自定义语法) |
| 插件生态 | 无 | 丰富(tpm、tmux-resurrect等) |
| RHEL/Fedora状态 | 自RHEL 8起移除 | 默认包含 |
| 串口支持 | 支持(screen /dev/ttyUSB0) |
不支持 |
| 学习资源 | 成熟但较旧 | 丰富且时新 |
适合使用Screen的场景:
- 需要串口访问(
screen /dev/ttyUSB0 115200) - 所在系统预装了Screen但没有tmux
- 只需要简单的分离/重连工作流
适合使用tmux的场景:
- 需要分离后仍然保留的窗格布局
- 需要活跃的插件生态
- 使用RHEL 8+或Fedora(软件仓库中没有Screen)
- 需要通过脚本创建窗口和窗格
两个工具处理核心用例(SSH断开后保持进程运行)的能力相同。如果你是新手,tmux有更大的社区动力和更好的默认配置。如果Screen已经是你工作流的一部分,没有迫切的理由需要切换。参阅我们的tmux教程获取完整指南。
常见Screen问题排查
显示"There is a screen on ... (Attached)"但你并未连接
这发生在SSH崩溃之后。旧连接没有正常分离。
screen -D -r session_name
这会强制分离残留连接并重新连接你的终端。
会话列表中出现Dead会话
服务器重启或崩溃后,有时会话会显示为(Dead)。
screen -wipe
输出:
There are screens on:
12345.old_session (Dead ???)
Removed dead screens.
1 socket wiped out.
这会移除过期的socket文件。运行screen -ls确认它们已被清除。
终端冻结/不接受输入
你可能不小心按了Ctrl-a s。这是XOFF流控制信号,会暂停终端输出。
修复方法:
Ctrl-a q
这会发送XON恢复输出。如果你从不使用流控制,可以在.screenrc中禁用它:
defflow off
Screen显示乱码
你的终端和Screen在编码或颜色支持上存在分歧。在.screenrc中添加:
defutf8 on
term screen-256color
然后启动新会话。已有的会话不会应用.screenrc的更改。
Screen的日志在哪里?
Screen本身不会写入系统日志。要启用每个窗口的日志记录:
Ctrl-a H
这会切换当前窗口的日志记录。日志保存到你启动会话时所在目录的screenlog.N文件中。N对应窗口编号。
检查Screen是否在系统级别运行:
ps aux | grep screen
常用CLI参数参考
| 参数 | 描述 | 示例 |
|---|---|---|
-S name |
启动命名会话 | screen -S myapp |
-r [name] |
重新连接到已分离的会话 | screen -r myapp |
-d -r name |
分离远端,在此处重连 | screen -d -r myapp |
-D -r name |
强制分离并重连 | screen -D -r myapp |
-x name |
连接到已连接的会话(多显示模式) | screen -x myapp |
-ls |
列出所有会话 | screen -ls |
-wipe |
移除Dead会话 | screen -wipe |
-X command |
向运行中的会话发送命令 | screen -S myapp -X quit |
-dmS name |
启动后台命名会话 | screen -dmS daemon |
-L |
从启动时开启日志 | screen -L -S myapp |
以后台模式启动会话(-dmS)在需要通过脚本或systemd单元启动Screen会话而无需交互终端时非常有用。
Copyright 2026 Virtua.Cloud. All rights reserved.