在Expect中使用进程替换<()>添加SSH密钥对是否可行?
在Expect中使用进程替换<()>添加SSH密钥对是否可行?
问题场景
尝试通过Expect配合Bash进程替换<()直接传递SSH私钥给ssh-add,使用的代码如下:
ssh_key=""" ----PRIVATE----- .... """ expect <<- EOF spawn ssh-add <(echo "${ssh_key}") expect "Enter passphrase" send "$password" expect eof EOF
执行后触发报错:
Trying to add key to SSH agent... extra characters after close-quote while executing "spawn ssh-add <(echo "----PRIVATE----- ...." Failed to add key to
结论:直接使用不可行,需调整实现方式
报错原因
- Expect不支持Bash进程替换:
<()是Bash专属的进程替换语法,Expect的spawn命令无法识别该语法,无法正确解析执行。 - 引号解析冲突:
ssh_key变量包含换行和未转义的引号,在Expect脚本中展开后,echo "${ssh_key}"的双引号会与外层Expect的双引号发生冲突,导致Expect解析时出现引号不匹配,触发extra characters after close-quote错误。
可行解决方案
方案1:临时文件中转(推荐,兼容性好)
先将私钥写入临时文件,再通过ssh-add加载,使用完成后删除临时文件:
ssh_key=""" ----PRIVATE----- .... """ # 创建临时文件存储私钥 tmp_key=$(mktemp) echo "${ssh_key}" > "${tmp_key}" expect <<- EOF spawn ssh-add "${tmp_key}" expect "Enter passphrase" send "$password\r" # 必须添加回车符,否则密码无法正确提交 expect eof EOF # 清理临时文件 rm -f "${tmp_key}"
方案2:通过Bash包装执行(无需临时文件)
让Bash来处理进程替换逻辑,将ssh-add命令交给Bash执行,避免Expect解析不支持的语法:
ssh_key=""" ----PRIVATE----- .... """ expect <<- EOF spawn bash -c 'ssh-add <(echo "${ssh_key}")' expect "Enter passphrase" send "$password\r" expect eof EOF
注意:如果私钥内容中包含单引号,需要先对单引号进行转义(将
'替换为'\''),否则会破坏Bash命令的语法结构。
内容的提问来源于stack exchange,提问作者N. J
相关产品推荐
相关产品推荐

