在Linux服务器上通过screen挂起程序,以及利用reptyr从终端剥夺程序的控制权转交screen的方法
文章目录
- 在Linux服务器上通过screen挂起程序,以及利用reptyr从终端剥夺程序的控制权转交screen的方法
- 一、screen挂起程序的详细步骤
- 1. 安装 screen(如果未安装)
- 2. 启动 screen 会话
- 3. 运行程序
- 4. 将 screen 会话脱离(Detach)
- 5. 查看现有 screen 会话
- 6. 重新连接到 screen 会话
- 7. 终止 screen 会话
- 8. 常用 screen 快捷键
- 9. 提示与注意事项
- 二、利用reptyr从终端剥夺程序的控制权转交screen的方法,即让正在运行的程序转移到 `screen`(有限支持)
- 1. 使用 `reptyr` 工具
- 2. 使用 `disown` 和 `nohup`(不依赖 `screen`)
- 3.注意事项
- 三、可能遇到的问题
- 1.错误原因
- 2.解决方法
- 1. 检查当前 `ptrace_scope` 设置
- 2. 临时修改 `ptrace_scope`
- 3. 永久修改 `ptrace_scope`
- 4. 检查进程所有者
- 5. 再次尝试运行 reptyr
- 6. 如果仍然失败
- 3.注意事项
在Linux服务器上通过screen挂起程序,以及利用reptyr从终端剥夺程序的控制权转交screen的方法
在 Linux 服务器上使用 screen
命令可以创建一个虚拟终端会话,允许程序在后台运行,即使你断开 SSH 连接也能保持运行。
一、screen挂起程序的详细步骤
1. 安装 screen(如果未安装)
大多数 Linux 发行版默认包含 screen
,但如果没有,可以通过包管理器安装:
-
Ubuntu/Debian:
sudo apt update sudo apt install screen
-
CentOS/RHEL:
sudo yum install screen
-
Fedora:
sudo dnf install screen
2. 启动 screen 会话
-
登录到 Linux 服务器。
-
输入以下命令启动一个新的
screen
会话:screen
这会打开一个新的虚拟终端。你可以直接在这个终端中运行你的程序。
-
(可选)为会话命名,便于管理多个
screen
会话:screen -S session_name
替换
session_name
为你想要的名称,例如myprogram
。
3. 运行程序
在 screen
会话中运行你的程序。例如:
python3 my_script.py
或任何其他需要长时间运行的命令。
4. 将 screen 会话脱离(Detach)
运行程序后,你可以脱离 screen
会话,让程序在后台继续运行:
- 按下
Ctrl + A
,然后按d
。 - 你会看到类似
[detached from 12345.pts-0.hostname]
的提示,表示会话已脱离。
5. 查看现有 screen 会话
返回服务器后,列出所有 screen
会话:
screen -ls
输出示例:
There is a screen on:12345.myprogram (Detached)
1 Socket in /var/run/screen/S-username.
6. 重新连接到 screen 会话
使用以下命令重新连接到特定的 screen
会话:
screen -r session_name
或使用会话 ID:
screen -r 12345
如果只有一个会话,直接运行 screen -r
即可。
7. 终止 screen 会话
如果你想结束会话:
- 重新连接到会话(
screen -r session_name
)。 - 停止程序(例如按
Ctrl + C
)。 - 输入
exit
或按Ctrl + D
退出screen
会话。
或者,直接从外部终止:
screen -S session_name -X quit
8. 常用 screen 快捷键
Ctrl + A, d
:脱离当前会话。Ctrl + A, c
:在当前screen
中创建新窗口。Ctrl + A, n
:切换到下一个窗口。Ctrl + A, p
:切换到上一个窗口。Ctrl + A, k
:关闭当前窗口。
9. 提示与注意事项
-
检查会话状态:如果
screen -r
提示会话正在被使用,可能需要强制接管:screen -D -r session_name
-
持久化运行:
screen
适合长时间运行的程序(如 Python 脚本、服务器进程等),即使服务器重启,需重新启动screen
会话。 -
替代工具:如果需要更高级的功能,可以考虑
tmux
,它是screen
的现代替代品。
二、利用reptyr从终端剥夺程序的控制权转交screen的方法,即让正在运行的程序转移到 screen
(有限支持)
如果想将一个已经运行的程序暂存到 screen
中,情况稍微复杂,因为 screen
本身并不能直接接管已经在运行的进程(例如,已经在终端运行的程序)。如果程序已经在运行(例如在一个普通终端中),直接转移到 screen
比较困难,因为 Linux 进程通常绑定到启动它们的终端。以下是可能的解决方法:
1. 使用 reptyr
工具
reptyr
是一个专门的工具,可以将正在运行的进程附加到新的终端(如 screen
)。以下是具体步骤:
安装 reptyr:
-
Ubuntu/Debian:
sudo apt update sudo apt install reptyr
-
CentOS/RHEL:
sudo yum install reptyr
使用 reptyr:
-
找到正在运行的程序的进程 ID(PID):
ps aux | grep your_program_name
假设 PID 是
12345
。 -
启动一个新的
screen
会话:screen -S session_name
-
在
screen
会话中,使用reptyr
接管进程:reptyr 12345
-
程序的控制权会被转移到
screen
会话中。现在按Ctrl + A, d
脱离会话,程序会继续在screen
中运行。
注意:
-
reptyr
需要系统支持ptrace
,某些服务器可能需要调整权限:sudo sysctl -w kernel.yama.ptrace_scope=0
-
不是所有程序都能无缝转移,复杂程序(例如有图形界面或复杂终端交互的)可能出现问题。
2. 使用 disown
和 nohup
(不依赖 screen
)
如果无法使用 reptyr
,可以考虑将进程与当前终端分离:
-
暂停程序(假设程序在前台运行):
按Ctrl + Z
暂停程序,回到终端。 -
将程序放入后台并脱离终端:
bg disown
-
退出当前终端,程序会继续运行,但不会绑定到
screen
。
缺点:这种方式不会将程序放入 screen
,你无法重新连接到程序的终端。如果需要交互,screen
更合适。
3.注意事项
- 程序状态:如果程序不能被中断或重启(如正在处理关键任务),
reptyr
是唯一可行的方法。 - 权限问题:确保有权限操作进程(
reptyr
可能需要sudo
)。 - 替代工具:如果
screen
不满足需求,可以尝试tmux
,它也支持类似的会话管理功能,且更灵活。
三、可能遇到的问题
在尝试使用 reptyr
将 PID 为 1774986
的进程附加到新的终端时,遇到了错误提示:
Unable to attach to pid 1774986: Operation not permitted
The kernel denied permission while attaching. If your uid matches
the target's, check the value of /proc/sys/kernel/yama/ptrace_scope.
For more information, see /etc/sysctl.d/10-ptrace.conf
1.错误原因
这个错误表示内核拒绝了 reptyr
的 ptrace
操作(ptrace
是 reptyr
用来接管进程的系统调用)。在 Linux 系统中,ptrace
的权限受到内核参数 kernel.yama.ptrace_scope
的限制。默认情况下,某些 Linux 发行版(如 Ubuntu)设置了严格的 ptrace
权限,导致非特权用户无法附加到其他进程。
具体来说,/proc/sys/kernel/yama/ptrace_scope
控制 ptrace
的行为:
- 0:任何进程都可以被
ptrace
(无限制,适合开发环境)。 - 1(默认值):只有父进程或具有适当权限的进程可以
ptrace
子进程。 - 2 或更高:进一步限制,甚至可能完全禁用
ptrace
。
你的系统当前设置可能是 1
或更高,导致 reptyr
无法附加到 PID 1774986
。
2.解决方法
1. 检查当前 ptrace_scope
设置
运行以下命令查看当前设置:
cat /proc/sys/kernel/yama/ptrace_scope
- 如果输出是
1
或2
,说明ptrace
受到限制。 - 如果输出是
0
,说明ptrace
没有限制,但你仍可能遇到权限问题。
2. 临时修改 ptrace_scope
你可以临时将 ptrace_scope
设置为 0
以允许 reptyr
工作:
sudo sysctl -w kernel.yama.ptrace_scope=0
这会立即生效,但重启后会恢复默认值。
3. 永久修改 ptrace_scope
如果需要永久更改:
-
编辑
/etc/sysctl.conf
或/etc/sysctl.d/10-ptrace.conf
:sudo nano /etc/sysctl.d/10-ptrace.conf
-
找到或添加以下行:
kernel.yama.ptrace_scope = 0
-
保存文件并应用更改:
sudo sysctl -p /etc/sysctl.d/10-ptrace.conf
4. 检查进程所有者
确保你的用户 ID(UID)与目标进程(PID 1774986
)的 UID 匹配:
ps -p 1774986 -o user
-
如果进程不属于你的用户,可能需要
sudo
运行reptyr
:sudo reptyr 1774986
-
如果进程属于其他用户,你需要该用户的权限或使用
root
权限。
5. 再次尝试运行 reptyr
在修改 ptrace_scope
或确认权限后,重新运行:
reptyr 1774986
6. 如果仍然失败
-
检查 SELinux/AppArmor:某些系统(如 CentOS 或启用 AppArmor 的 Ubuntu)可能有额外的安全机制限制
ptrace
。尝试临时禁用:-
对于 SELinux:
sudo setenforce 0
-
对于 AppArmor,检查是否有针对
reptyr
的限制,可能需要调整配置文件。
-
-
确认进程状态:确保 PID
1774986
仍在运行:ps -p 1774986
-
使用
sudo
:如果权限问题仍然存在,尝试以root
身份运行:sudo reptyr 1774986
3.注意事项
- 安全性:将
ptrace_scope
设置为0
会降低系统安全性,仅建议在受信任的开发环境或个人服务器上使用。 - 程序类型:某些程序(例如有复杂终端交互或图形界面的进程)可能不适合用
reptyr
转移。 - 替代方案:如果
reptyr
无法满足需求,考虑:- 停止并在
screen
中重启程序(如果可行)。 - 使用
tmux
替代screen
,但转移已有进程仍需reptyr
。 - 使用
nohup
或disown
让进程脱离终端(但无法重新连接交互)。
- 停止并在