You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何封装交互式程序为支持管道的非交互式脚本?附passphrase2pgp实践

通用方案:将交互式TUI程序封装为非交互式批处理脚本

核心逻辑

要实现从stdin接收输入、仅向stdout输出目标内容的封装,关键要解决两个问题:自动响应程序的交互式提示,以及过滤掉无关输出只保留需要的内容。

一、用Expect处理交互式输入

Expect是处理交互式程序的标准工具,针对你的场景,需注意避开终端接管的坑,同时精准匹配提示并发送输入:

  • 禁用interact命令,避免管道输入时脚本异常退出
  • 从stdin读取输入内容(而非硬编码),适配管道传参
  • 匹配程序的密码提示文本,自动发送读取到的密码

示例脚本(my-keygen)

#!/usr/bin/expect -f

# 读取stdin中的密码,去除末尾换行符
set passphrase [read stdin]
regsub {\n$} $passphrase "" passphrase

# 启动目标程序
spawn passphrase2pgp

# 匹配密码提示并发送
expect "Enter passphrase:"
send "$passphrase\r"
# 处理确认密码的提示(如果有)
expect "Confirm passphrase:"
send "$passphrase\r"

# 等待程序执行完毕,捕获所有输出
expect eof

# 过滤并输出armored格式的私钥
set full_output [exp_out]
# 正则匹配PGP私钥块
if {[regexp {-----BEGIN PGP PRIVATE KEY BLOCK-----.*?-----END PGP PRIVATE KEY BLOCK-----} $full_output target_key]} {
    puts $target_key
}

二、脚本配置与测试

  1. 赋予执行权限:
chmod +x my-keygen
  1. 管道调用测试:
printf "your-password" | ./my-keygen | gpg --import

三、通用适配指南

针对其他交互式程序(如ssh-keygen),只需调整以下3个部分:

  • 提示匹配规则:比如ssh-keygen会提示Enter file in which to save the key、Enter passphrase,对应修改expect后的字符串
  • 输出过滤规则:如果是SSH私钥,匹配-----BEGIN RSA PRIVATE KEY-----到-----END RSA PRIVATE KEY-----的内容
  • 输入发送逻辑:根据程序需要的输入项,依次发送对应内容(比如ssh-keygen需要跳过文件名提示,可发送\r)

四、常见问题排查

  • 管道输入导致脚本提前退出:绝对不要用interact,改用read stdin读取输入,确保输入流被正确处理
  • 输出包含多余提示:用正则精准匹配目标输出块,只输出匹配结果,过滤掉程序的交互提示、日志等
  • 程序检测终端环境拒绝执行:在spawn前添加set env(TERM) vt100,模拟终端环境绕过检测

内容的提问来源于stack exchange,提问作者luochen1990

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:01:24