Anacron执行移除SSH密钥脚本无效问题求助
我正在学习使用Anacron实现任务自动化,参考了Anacron相关指南。我的需求是每日移除已保存的SSH密钥,虽可使用--timeout参数,但希望通过bash脚本手动实现。
脚本内容
remove-keys.sh内容:
SERVICE="ssh-agent" if pgrep -x "$SERVICE" >/dev/null then /usr/bin/ssh-add -D else : fi
Anacrontab配置
SHELL=/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin START_HOURS_RANGE=18-20 1 5 remove-keys source $HOME/.local/etc/cron.daily/remove-keys.sh
测试情况
- 手动执行
source remove-keys.sh时所有身份标识可被移除 - 已赋予脚本必要执行权限,Anacron语法测试通过
- 使用
source是为让脚本命令在当前bash会话中执行 - 测试Anacron的命令:
anacron -fn -t $HOME/.local/etc/anacrontab -S $HOME/.var/spool/anacron
但执行后查看ssh-add -L,所有身份标识仍存在。
补充说明:我在WSL2上使用Ubuntu20.04,通过keychain复用ssh-agent以持久化身份标识(多shell会话时必需),因此身份标识在WSL关闭前无超时限制。
核心问题在于Anacron运行的独立会话无法访问keychain维护的ssh-agent环境变量,导致ssh-add -D找不到对应的agent进程。
为什么手动执行有效,Anacron执行无效?
手动执行时,你的shell会话已经通过keychain加载了SSH_AUTH_SOCK和SSH_AGENT_PID这两个关键环境变量,ssh-add能定位到正确的agent进程。但Anacron运行在无交互式的独立会话中,默认不会继承这些用户会话的环境变量——哪怕脚本检测到ssh-agent进程存在,ssh-add也无法与它建立通信。
另外,你在Anacrontab里用source完全无效:Anacron的任务是在它自己启动的临时shell进程里执行,source只会影响这个临时进程,和你的用户shell会话没有任何关联,这和手动source的场景本质不同。
解决方案步骤
修改脚本,加载keychain环境变量
keychain会把ssh-agent的socket路径等信息存放在$HOME/.keychain/<hostname>-sh这类文件中,我们需要在脚本里加载这个文件,让ssh-add能找到正确的agent:# 加载keychain生成的环境变量文件 KEYCHAIN_ENV="$HOME/.keychain/$(hostname)-sh" if [ -f "$KEYCHAIN_ENV" ]; then . "$KEYCHAIN_ENV" fi # 仅当能找到有效ssh-agent socket时执行移除操作 if [ -n "$SSH_AUTH_SOCK" ] && [ -S "$SSH_AUTH_SOCK" ]; then /usr/bin/ssh-add -D fi修改Anacrontab,直接执行脚本
既然脚本已经处理了环境变量加载,直接执行脚本即可,不需要source,同时建议改用bash避免sh的兼容性问题:SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin:$HOME/.local/bin START_HOURS_RANGE=18-20 1 5 remove-keys $HOME/.local/etc/cron.daily/remove-keys.sh验证脚本与Anacron任务
先直接运行脚本(不要source),确认ssh-add -L返回空:$HOME/.local/etc/cron.daily/remove-keys.sh没问题后再用你的测试命令验证Anacron:
anacron -fn -t $HOME/.local/etc/anacrontab -S $HOME/.var/spool/anacron
额外说明
- 如果你的keychain环境文件命名不同(比如带
-bash后缀),可以用ls $HOME/.keychain/查看具体文件名,替换脚本里的KEYCHAIN_ENV路径。 - WSL2环境下,确保keychain的登录配置正确,每次启动shell都会自动加载对应的环境变量文件。
内容的提问来源于stack exchange,提问作者GreninjaShuriken4

