crontab 中直接调用 gpg 加密失败,因缺少 GPG_AGENT_INFO 等环境变量及 tty;需显式设置 GPG_TTY、--batch --yes、--homedir,并用 --passphrase-file 安全传入口令,配合校验与延迟删除确保可靠性。
crontab 里直接调用 gpg 加密会失败?
因为 gpg 在非交互环境下默认尝试连接 agent,而 cron 启动的 shell 没有继承桌面会话的 gpg_agent_info 或 gnupghome 环境变量,导致超时或报错 gpg: signing failed: no such file or directory。
- 在 crontab 条目开头显式加载环境:
GPG_TTY=$(tty) && export GPG_TTY(即使 cron 没有 tty,这步也能避免某些版本卡住) - 强制使用批处理模式:
--batch --yes,禁用所有交互提示 - 指定密钥环路径:
--homedir /path/to/your/gnupghome,别依赖默认~/.gnupg - 用
--passphrase-fd 0配合 echo 传入口令(不推荐明文),更安全的做法是用gpg-preset-passphrase预载密钥(需启用 gpg-agent 并配置allow-loopback-pinentry)
备份脚本里怎么安全传入加密口令?
硬编码口令到脚本或环境变量里等于裸奔;用文件读取又得管权限(chmod 600 必须做,否则 gpg 会拒绝读取)。
- 推荐方式:把口令存在只有 root 可读的文件中,比如
/etc/backup/gpg-passphrase,然后在脚本里写:gpg --batch --yes --passphrase-file /etc/backup/gpg-passphrase --encrypt --recipient your-key-id backup.tar.gz - 注意
--passphrase-file读取的是第一行,末尾换行符会被当作口令一部分——用echo -n "xxx" > file写入 - 如果用
gpg --symmetric(对称加密),同样适用该方式;但别用-c简写,它可能触发交互
加密后删源文件?还是保留原始备份?
删了就没了回滚余地。自动流程里「先加密、再校验、最后删」才是可靠链路。
- 加密后立刻用
gpg --list-packets或简单解密测试:gpg --batch --yes --passphrase-file ... --decrypt backup.tar.gz.gpg | head -c1 >/dev/null,验证能读出内容 - 比对加密前后文件大小是否合理(
.gpg通常比原文件大 1–5%,异常大可能是加密失败或被截断) - 确认解密可用后,再用
rm backup.tar.gz;建议加-i开关或先 mv 到临时目录观察一天 - 真正生产环境,保留未加密备份 24 小时是底线,不是可选项
定时任务执行时间点和日志怎么不踩坑?
crontab 默认用系统 locale 和 PATH,很多脚本在终端能跑,cron 里就报 command not found。
- 在 crontab 条目里写全路径:
/usr/bin/gpg而不是gpg,查路径用which gpg - 每条任务重定向输出:
> /var/log/backup-encrypt.log 2>&1,否则错误全丢进黑洞 - 避免分钟级高频任务——
gpg加密大文件很吃 CPU,连续触发可能堆积锁或耗尽内存 - 用
run-parts管理多个备份任务时,确保每个脚本开头都有#!/bin/bash和set -e,失败立刻中断











