使用spawn和expect处理PGP加密多行确认提示问题
问题描述
使用PGP加密文件时,导入密钥后每次运行脚本都会触发密钥确认提示。尝试用spawn和expect实现自动化,但PGP输出的多行提示包含特殊字符,复制文本或用正则都无法成功匹配,需要匹配提示并自动发送y响应。当前脚本如下:
/usr/bin/expect -d <<-!EXP >> /logname 2>&1 spawn /usr/bin/gpg --encrypt -r <publickey> <filename> >> logname 2>&1 sleep 1 expect " Pub <key> IT security (contact us at email <its@abc.com> Primary Key fingerprint: 339D O998 Subkey fingerprint: F779 D999 It is not certain that the key belongs to the person named in the user ID. If you *really* know what you are doing, you may answer the next question with yes. Use this key anyway? (y/N)" sleep 1 send "y\r" expect eof !EXP
解决方案
方案一:直接修改gpg命令跳过确认(推荐)
无需依赖expect,给gpg添加参数直接信任密钥,彻底跳过确认提示:
gpg --encrypt -r <publickey> --trust-model always <filename>
也可使用--batch+--yes组合实现静默执行:
gpg --encrypt -r <publickey> --batch --yes <filename>
这种方式比expect更可靠,避免了匹配文本的各种问题。
方案二:修复expect脚本的匹配逻辑
如果必须使用expect,可以简化匹配规则,放弃整段文本匹配,只针对提示的最后一行做匹配,避开多行格式和特殊字符的干扰:
/usr/bin/expect -d <<-!EXP >> /logname 2>&1 spawn /usr/bin/gpg --encrypt -r <publickey> <filename> # 仅匹配提示的关键行,避免多行格式问题 expect "Use this key anyway? (y/N)" send "y\r" expect eof !EXP
额外修正点:
- 修正脚本中的路径错误:
\usr\bin\expect改为/usr/bin/expect,/ur/bin/gpg改为/usr/bin/gpg - 移除
spawn命令后的sleep 1和多余重定向,expect会自动等待输出,无需手动休眠 - 若匹配仍失败,改用正则表达式匹配并转义特殊字符:
expect -re {Use this key anyway? \([yN]\)}
方案三:预先标记密钥为可信
在生产环境中,也可以一次性将目标密钥标记为可信,后续加密操作不再触发确认提示:
gpg --edit-key <publickey> trust quit
执行后按照提示选择信任级别(例如选5表示完全信任),完成后即可永久跳过该密钥的确认步骤。
内容的提问来源于stack exchange,提问作者Giri Sreerangam
相关产品推荐
相关产品推荐

