如何使用Python实现带签名的rpmbuild自动化执行?
解决rpmbuild调用gpg导致stdin重定向卡住的问题
我之前也踩过一模一样的坑!问题的核心是gpg默认会直接读取终端(/dev/tty)的输入,而不是继承父进程的stdin——哪怕你用subprocess的管道重定向了stdin,rpmbuild内部调用的gpg也会绕过这个管道,直接去终端要密码,这就是你的程序一直卡住的原因。
下面是几个亲测有效的解决方案:
1. 给gpg指定密码输入的文件描述符
你可以通过rpmbuild的宏配置,让gpg从指定的文件描述符读取密码,绕开终端。比如:
- 先准备好gpg密码内容
- 在调用rpmbuild时,设置
%__gpg_cmd宏,加上--passphrase-fd 3参数,让gpg从文件描述符3读取密码
示例代码:
import subprocess passphrase = b"your_gpg_passphrase\n" cmd = ["rpmbuild", "-ba", "your_spec_file.spec", "--define", "__gpg_cmd gpg --passphrase-fd 3"] with subprocess.Popen(cmd, stdin=subprocess.PIPE, pass_fds=[3]) as p: # 把密码写入指定的文件描述符 with open(3, 'wb') as f: f.write(passphrase) p.communicate()
2. 用pexpect模拟终端交互
如果不想修改gpg的调用参数,可以用pexpect库(先通过pip install pexpect安装),它能直接模拟终端会话,和gpg的终端输入交互:
import pexpect # 启动rpmbuild进程 child = pexpect.spawn("rpmbuild -ba your_spec_file.spec") # 匹配gpg的密码提示语句 child.expect("Enter passphrase:") # 发送预设的密码 child.sendline("your_gpg_passphrase") # 等待进程执行完成并获取输出 child.expect(pexpect.EOF) print(child.before.decode())
3. 用gpg-agent缓存密码
如果你的环境允许,配置gpg-agent自动缓存密码是更安全的方案,后续调用gpg时无需手动输入:
- 先启动gpg-agent:
gpg-agent --daemon - 手动执行一次需要密码的gpg操作(比如
gpg --sign test.txt),输入密码后,agent会缓存一段时间 - 确保脚本的环境变量
GPG_AGENT_INFO正确继承,之后rpmbuild调用gpg时会自动使用agent的缓存,不会再弹出密码提示
内容的提问来源于stack exchange,提问作者spanishgum
相关产品推荐
相关产品推荐

