4149 字
21 分钟
常用命令总结(一):ssh-agent, screen, reptyr, du

场景:SSH 连上服务器正装着依赖,突然下课/断网/下班——SSH 一断任务全没。screen 让任务脱离 SSH 独立运行,下课提包跑路不丢进度;reptyr 紧急补救忘开 screen 的翻车现场;du 排查磁盘被谁吃光。本文用四个命令逐一击破。

1. ssh-agent:免密 SSH 密钥管理#

ssh-agent 是一个后台守护进程,用于缓存 SSH 私钥的解密密码(passphrase)。加载一次密钥后,后续所有 SSH 连接无需反复输入密码。

1.1 手动启动#

Terminal window
# 启动 agent(输出环境变量)
eval "$(ssh-agent -s)"
# Agent pid 12345
# 添加密钥
ssh-add ~/.ssh/id_ed25519
# Enter passphrase for ~/.ssh/id_ed25519: ****
# Identity added: ~/.ssh/id_ed25519
# 查看已加载的密钥
ssh-add -l
# 256 SHA256:xxxx... user@host (ED25519)

1.2 常用参数#

命令 / 参数说明
ssh-agent -s启动 agent,输出 bash 可用的环境变量
ssh-agent -c启动 agent,输出 csh/tcsh 可用的环境变量
ssh-agent -k关闭当前 agent
ssh-agent -t 3600密钥缓存有效期(秒),默认永久
ssh-add <keyfile>添加指定私钥到 agent
ssh-add -l列出已加载的密钥指纹
ssh-add -L列出已加载密钥的公钥
ssh-add -d <keyfile>从 agent 中移除指定密钥
ssh-add -D移除所有密钥
ssh-add -t 3600添加密钥并设置缓存时间(秒)
ssh-add -c添加密钥,每次使用需确认(部分系统不支持)

1.3 配置 ssh-agent 自动启动#

手动启动 agent 的问题是:每次新开终端都要重新来过。以下三种方案可按需选用。

方案一:~/.bashrc 自动复用(推荐)#

~/.bashrc 末尾添加,让所有终端共享同一个 agent 进程:

Terminal window
# ssh-agent 自动启动(仅启动一次,多终端复用)
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR:-/tmp}/ssh-agent-$USER.sock"
if ! pgrep -u "$USER" ssh-agent > /dev/null; then
eval "$(ssh-agent -s -a "$SSH_AUTH_SOCK")" > /dev/null
fi
# 如果有 agent 但没有密钥,静默添加
ssh-add -l >/dev/null 2>&1 || ssh-add ~/.ssh/id_ed25519 2>/dev/null

解释:用 pgrep 检查是否已有 agent 进程,没有则新建;通过 -a 指定固定 socket 路径,让所有终端访问同一个 agent。

方案二:systemd 用户服务(systemd 系统)#

创建 ~/.config/systemd/user/ssh-agent.service

[Unit]
Description=SSH authentication agent
[Service]
Type=simple
ExecStart=/usr/bin/ssh-agent -D -a "${XDG_RUNTIME_DIR}/ssh-agent.sock"
ExecStartPost=/usr/bin/ssh-add ~/.ssh/id_ed25519
[Install]
WantedBy=default.target

启用并启动:

Terminal window
systemctl --user daemon-reload
systemctl --user enable --now ssh-agent.service

然后在 ~/.bashrc 中设置环境变量即可:

Terminal window
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/ssh-agent.sock"

方案三:桌面环境自动管理#

大多数 Linux 桌面环境(GNOME、KDE、macOS)的会话管理器已自动启动 ssh-agentgnome-keyring-daemon,无需手动配置。可通过以下命令验证:

Terminal window
echo $SSH_AUTH_SOCK
# /run/user/1000/keyring/ssh → 桌面环境已管理
env | grep SSH

1.4 agent forwarding(转发)#

从机器 A SSH 到机器 B 时,让 B 也能复用 A 上的密钥:

Terminal window
# 连接时启用转发
ssh -A user@remote_host
# 或在 ~/.ssh/config 中永久配置
Host myserver
HostName 192.168.1.100
ForwardAgent yes

⚠️ 安全提醒:ForwardAgent 会让远程机器的 root 用户在连接期间使用你的密钥。仅在信任的服务器上开启。

2. screen:任务脱离 SSH 运行#

screen 是一个终端复用器,允许你创建多个虚拟终端窗口,即使 SSH 断开,里面的任务也会继续运行。

2.1 安装#

Terminal window
# Debian/Ubuntu
sudo apt install screen -y
# RHEL/CentOS/Fedora
sudo dnf install screen -y

2.2 基本使用#

Terminal window
# 创建新会话(可命名)
screen -S mytask
# 在 screen 中运行任务
python train_model.py
# 安全脱离(detach):Ctrl+A 然后按 D
# 回到终端后,列出所有会话
screen -ls
# There is a screen on:
# 12345.mytask (Detached)
# 重新连接(attach)
screen -r mytask

💡 只输 screen 也能快速启动,screen 会自动生成一个 pid.tty.host 格式的会话名。进入后随时可以用 Ctrl+A :sessionname 新名字 重命名当前会话,后续再用 screen -r 新名字 附加上去。

2.3 常用参数#

命令说明
screen快速创建会话(自动生成名称)
screen -S <name>创建命名会话
screen -ls列出所有 screen 会话
screen -r <name>恢复(attach)指定会话
screen -r <pid>按进程号恢复会话
screen -d <name>强制将 attached 会话转为 detached 状态
screen -d -r <name>强制 detach 后再 attach(抢回会话)
screen -x <name>多终端共享模式(两人同时看同一画面)
screen -X quit关闭指定会话
screen -wipe清理已死掉的会话记录

2.4 快捷键一览#

进入 screen 后,所有操作以 Ctrl+A 为前缀键:

快捷键功能
Ctrl+A D脱离(detach)
Ctrl+A C创建新窗口
Ctrl+A N切换到下一个窗口
Ctrl+A P切换到上一个窗口
Ctrl+A "列出窗口列表(可切换)
Ctrl+A A重命名当前窗口
Ctrl+A K关闭当前窗口
Ctrl+A [进入滚动模式(翻阅输出)
Ctrl+A W显示窗口列表(底部条)
Ctrl+A 0-9切换到指定编号的窗口

2.5 记录输出到文件#

screen 自带 -L 日志功能,但受程序输出缓冲影响,经常明明有输出文件却为空,排查和配置成本较高。如果想记录命令的输出,直接用 shell 重定向更简单可靠:

Terminal window
# 覆盖写入(每次清空旧内容)
./task.sh > output.log 2>&1
# 追加写入(保留历史)
./task.sh >> output.log 2>> error.log
# tee:同时看屏幕输出 + 写入文件
./task.sh 2>&1 | tee output.log
# 追加模式
./task.sh 2>&1 | tee -a output.log
写法stdoutstderr文件模式屏幕可见
> file写入 file仍显示在屏幕覆盖
>> file追加到 file仍显示在屏幕追加
2>&1 > file写入 file写入 file覆盖
2>&1 >> file追加到 file追加到 file追加
2>&1 | tee file写入 file写入 file覆盖
2>&1 | tee -a file追加到 file追加到 file追加

2>&1 是什么? 2> 表示 stderr 重定向,&1 表示目标为「stdout 当前指向的位置」。整句意思:把 stderr 合并到 stdout,让它们走同一条路

文件描述符含义
0 / stdin标准输入
1 / stdout标准输出
2 / stderr标准错误

不加 2>&1 有什么影响?

Terminal window
./task.sh > log.txt # stdout → 文件, stderr → 屏幕(丢失!)
./task.sh > log.txt 2>&1 # stdout + stderr → 文件(完整)

不加的话报错信息不会进文件,排查问题时日志里只有正常输出,异常全丢了——这是最常见的日志遗漏原因。

2.6 配置建议 (~/.screenrc)#

# 关闭烦人的启动提示
startup_message off
# 始终显示窗口列表
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}]'
# 回滚缓冲区行数
defscrollback 10000
# 防呆:退出时不误关窗口
bind q

bind q 设为空后,Ctrl+A Q 就不会误关了,想退出用 Ctrl+A K 或直接 exit

2.7 重新连接后上翻输出#

screen -r 附加上去后发现鼠标滚轮、终端滚动条都翻不动历史输出?这是 screen 最常见的新手困惑。原因:screen 维护自己的回滚缓冲区(scrollback buffer),终端的滚动条只能翻终端自身的输出,翻不到 screen 内部的历史。

解决方法很简单:进入 copy/scrollback 模式

Terminal window
# 进入 copy 模式,方向键/j k 翻行,PgUp/PgDn 翻页
Ctrl+A [

注意是 Ctrl+A [(左方括号),不是 Ctrl+A Esc。后者是 tmux 的快捷键,在 screen 中会报 Must be on a window layer

在 copy 模式下的操作方式(类 vi 键位):

按键功能
/ j k上下逐行移动
Ctrl+F / Ctrl+B上/下翻页
PgUp / PgDn上/下翻半页
g / G跳到顶部/底部
/关键词向下搜索
?关键词向上搜索
n / N下一个/上一个匹配
EscEnter退出 copy 模式

缓冲区大小~/.screenrc 中的 defscrollback 控制:

# 默认 100 行,建议加大
defscrollback 10000

改完新创建的 screen 窗口生效,已有窗口可在 screen 内执行 Ctrl+A :scrollback 10000 临时调整。

不想每次手动进 copy 模式? 启动任务时直接重定向输出到文件:./task.sh > task.log 2>&1,然后用 tail -f / less 在外部终端直接翻看历史输出,体验更好。

3. reptyr:接管正在运行的进程#

reptyr 可以把一个已经在终端中运行的进程”抓”进 screen/tmux 会话里。比如忘记用 screen 直接跑了 sudo apt upgrade,可以用 reptyr 把它迁移进去。

名字来源Re-attach PTY + r → “重新挂接到伪终端”。PTY(pseudo-terminal)就是 Linux 里虚拟终端的缩写。记法:re-pty-r = 重新(re)挂到终端(pty)上。

3.1 安装#

Terminal window
# Debian/Ubuntu
sudo apt install reptyr -y
# RHEL/Fedora
sudo dnf install reptyr -y

3.2 紧急补救:任务已在跑,马上要关电脑/断 SSH#

这是最常见的翻车场景:一个耗时任务跑起来了,此刻你必须断开连接(关笔记本、切网络、下班走人),但没开 screen。补救流程如下:

Terminal window
# 第 1 步:在任务所在终端中,按 Ctrl+Z 暂停进程
# (假设任务叫 mytask,暂停后会显示)
# [1]+ 已停止 ./mytask
# 第 2 步:把进程放到后台继续跑
bg
# [1]+ ./mytask &
# 第 3 步:脱离 shell 的管控,避免退出 shell 时进程被杀
disown -h %1
# 第 4 步:确认进程仍在运行(disown -h 后 jobs 仍可见)
jobs -l
# [1]+ 12345 运行中 ./mytask &
# 现在可以安全退出 SSH / 关闭终端了。

关键说明

步骤作用
Ctrl+Z暂停进程,让你有机会操作
bg让进程在后台继续运行。不要用 fgfg 拉回前台就没法脱离终端了
disown -h %1标记进程为 SIGHUP 免疫,但仍保留在 jobs 列表中(方便下一步用 jobs -l 确认 PID)

disown 的两种用法区别

Terminal window
disown %1 # 完全移除:作业从 jobs 列表消失,shell 退出不杀进程
disown -h %1 # 标记但不移除:作业仍显示在 jobs 列表中,shell 退出不杀进程
disown %1disown -h %1
行为将作业从 shell 作业表彻底移除保留在作业表中,但标记为SIGHUP 免疫
jobs 可见❌ 不再显示✅ 仍可见,但 bg/fg 对其无效
shell 退出不杀进程不杀进程
典型场景干净利落,不留痕迹想事后用 jobs 看一眼 PID,又不想被 SIGHUP 杀掉

💡 对于「紧急补救 → 之后 reptyr 找回」这个场景,两者效果相同。推荐 disown 无参数,干净省事。disown -h 的好处是你退出前还能用 jobs -l 再看一眼 PID,方便记下来。

⚠️ 仅限断开 SSH 的场景。如果任务是跑在本地机器上,直接关机(poweroff)进程一定会死,disown 救不了。唯一的选择是休眠/挂起代替关机。

之后如何找回进程#

重新 SSH 登录后,用 reptyr 接管:

Terminal window
# 找到进程 PID
pgrep -f mytask
# 12345
# 先开 screen
screen -S rescue
# 在 screen 内接管
reptyr 12345

关于日志:中间这段输出能看到吗?#

不能。 disown 后退出 SSH 的那段时间,进程的 stdout/stderr 指向一个已经不复存在的终端,输出直接丢弃(写入 /dev/null),无法恢复。

如果在意中间这段输出,三种补救思路:

Terminal window
# 思路 1(事前最佳):启动时就把输出重定向到文件
./mytask > task.log 2>&1
# 思路 2(事后补救 — 高级):用 gdb 重定向已在运行的进程的输出
# 需要安装 gdb,且进程需用调试符号编译
gdb -p 12345 -batch \
-ex 'p dup2(open("/tmp/task.log", 577, 0644), 1)' \
-ex 'p dup2(open("/tmp/task.log", 577, 0644), 2)' \
-ex detach
# 577 = O_WRONLY|O_CREAT|O_APPEND, 后续输出会写入 /tmp/task.log
# 思路 3(保底):reptyr 接管后马上在 screen 中开启日志
# Ctrl+A H → 今后所有输出都记录到 screenlog.0

💡 最佳实践:预期要跑长任务时,永远先 screen -S tasknamedisown + reptyr 是紧急补救手段,中间丢日志是无法避免的代价。

3.3 常规接管场景#

如果不需要断开连接,只是想把当前终端的进程迁移到 screen 里(比如终端太乱、想组织到 screen 窗口中):

Terminal window
# 终端 1:运行一个命令
ping google.com
# 1. Ctrl+Z 暂停
# 2. bg 放后台
bg
# 3. 查看 PID
jobs -l
# [1]+ 12345 运行中 ping google.com &
# 4. 启动 screen
screen -S rescue
# 5. 在 screen 中接管
reptyr 12345

3.4 权限问题解决#

如果遇到 Unable to attach to pid

Terminal window
# 临时允许非 root 用户使用 ptrace
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
# 永久生效
echo "kernel.yama.ptrace_scope = 0" | sudo tee /etc/sysctl.d/10-ptrace.conf
sudo sysctl -p /etc/sysctl.d/10-ptrace.conf
ptrace_scope 值含义
0任何进程可 ptrace 任何同 UID 进程(最宽松)
1仅父进程可 ptrace 子进程(默认,限制 reptyr)
2仅 root 可用 ptrace(最严格)
3完全禁用 ptrace

3.5 常用参数#

命令 / 参数说明
reptyr <PID>接管指定 PID 的进程
reptyr -T窃取目标整个终端会话(实验性,更可靠,会附加该终端所有进程)
reptyr -s强制附加 fds 0-2,即使目标进程未挂载在 tty 上
reptyr -v显示版本号
reptyr -V输出详细调试信息

4. du:查看文件夹磁盘占用#

duDisk Usage)用于统计文件和目录占用的磁盘空间。它是排查磁盘空间不足的第一利器

名字来源Disk Usage(磁盘使用量)。两个字母,好记——就是”看看磁盘被谁用了”。同类命令还有 dfDisk Free,磁盘剩余空间)和 ddData Duplicator,数据拷贝)。

4.1 基本用法#

Terminal window
# 查看当前目录总大小
du -sh .
# 4.2G .
# 查看当前目录下各子目录大小(一层深度)
du -sh */
# 1.2G Documents/
# 800M Downloads/
# 2.1G Projects/

4.2 完整参数表#

参数全称说明
-h--human-readable人类可读格式(K, M, G)
-s--summarize仅显示总计
-c--total最后一行输出总和
-a--all显示所有文件,而非仅目录
-d <N>--max-depth=N限制递归深度
--time同时显示最后修改时间
--time=ctime显示状态变更时间 / atime 访问时间
-x--one-file-system不跨文件系统(跳过挂载点)
-L--dereference追踪符号链接
--exclude=<模式>排除匹配的文件/目录
--threshold=<大小>只显示大于指定大小的项(如 +100M
-b--bytes以字节为单位(纯数字,适合脚本处理)
-B<N>--block-size=N指定块大小(如 -BM = 1M 块)
--apparent-size显示文件表观大小而非实际磁盘占用
-0--null输出用 NULL 分隔(配合 xargs -0

4.3 实用场景及命令#

排查根目录磁盘占用大户#

Terminal window
# 从根目录开始,一层深度,按大小排序
sudo du -h -d 1 / 2>/dev/null | sort -rh | head -20
# 输出示例:
# 16G /
# 8.4G /usr
# 5.1G /var
# 2.3G /home
# 890M /opt

查看当前目录下最大的 10 个子目录#

Terminal window
du -sh * 2>/dev/null | sort -rh | head -10

找出某个目录下的大文件(>100MB)#

Terminal window
# 显示详细文件大小
du -ah /path/to/dir | sort -rh | head -20
# 或仅显示大于 100M 的
du -ah /path/to/dir --threshold=+100M | sort -rh

不跨文件系统(跳过 /mnt、/media 等挂载点)#

Terminal window
du -sh -x /*

为什么重要:排查根分区爆满时,如果不加 -xdu 会钻到挂载的外部硬盘、NFS 共享等子目录中,把它们的空间也算进来,导致混淆。

结合 find 精确排查#

Terminal window
# 查找 /var 下大于 500M 的文件
find /var -type f -size +500M -exec ls -lh {} \; 2>/dev/null
# 查找最近 7 天内修改过的大文件(>100M)
find / -type f -size +100M -mtime -7 -exec ls -lh {} \; 2>/dev/null

4.4 du vs df 的区别#

dudf
用途估算文件/目录的实际占用空间查看文件系统层面的空间使用
来源遍历目录树,累加文件大小读取文件系统超级块中的元数据
场景”哪个目录占了我的空间?""分区还有多少空间?“
差异比 df 小(不含已删除但未释放的文件)比 du 大(含已删但仍占用的)
Terminal window
# 对比两者差异
df -h /
# /dev/sda1 50G 42G 5.5G 89% /
du -sh / --exclude=/proc --exclude=/sys 2>/dev/null
# 37G /
# 相差 5G → 可能有进程持有已删除文件

dfdu 大很多时,通常是某进程仍持有已删除文件的句柄。排查方法:

Terminal window
# 查看已删除但仍被占用的文件
sudo lsof +L1 | head -30
# 找到后重启对应进程或 kill 掉持有句柄的 PID

4.5 ncdu:交互式 du(可选利器)#

Terminal window
sudo apt install ncdu -y
# 交互式浏览
ncdu /
# 导出分析报告
ncdu -o disk_scan.json /
# 在另一台机器上查看
ncdu -f disk_scan.json

ncdu 界面中,方向键导航、d 删除、s 按大小排序、n 按名称排序,q 退出。

5. 组合技:实战流程#

场景:SSH 到服务器,想跑一个耗时脚本,中途网络断了就白费 —— 用 screen 兜底。

Terminal window
# 1. SSH 登录服务器
ssh user@myserver
# 2. 启动 screen 会话
screen -S work
# 3. 在 screen 中运行任务
./long_running_script.sh
# 4. 安全脱离: Ctrl+A 然后 D
# 5. 断开 SSH,回家吃饭
exit
# 6. 回家后重新 SSH 登录,恢复会话
ssh user@myserver
screen -r work
# 任务还在跑,输出完好

参考链接#

常用命令总结(一):ssh-agent, screen, reptyr, du
https://www.mintlab.top/posts/learn/ssh-screen-reptyr-du/
作者
Mint
发布于
2026-06-17
许可协议
CC BY-NC-SA 4.0
发表评论

输入用户名和邮箱后自动检查登录状态。登录后用户名和邮箱将被绑定, 只可以修改头像和主页链接。

未登录
昵称
邮箱
填写头像链接与主页链接

头像链接为空默认使用gravatar头像

头像
主页
人机验证
评论列表

以下是可爱的评论们:

暂无评论, 呜呜, 快来评论喵!