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

含Expect的Bash脚本执行SSH调用时出现引号错误排查

引号解析冲突导致的Expect脚本SSH报错排查

核心原因:Expect与Bash的引号处理逻辑不一致

  • 手动执行ssh -t anon@machine 'bash -c "cd /tmp;"'时,本地Bash会优先解析外层单引号:单引号会屏蔽内部所有特殊字符(包括双引号),最终传给SSH的命令是bash -c "cd /tmp;",远程Bash能正确识别嵌套引号并执行。
  • 但在你的Expect脚本中,ssh_param定义为"-t ${scp_user}${_machine} 'bash -c \"cd /tmp;\"'"时,问题出在:
    • Expect不识别Bash的单引号语法,外层单引号在Expect里只是普通字符,不会起到“保护内部字符串”的作用。
    • Expect会先解析转义的双引号\",最终传给SSH的命令包含了多余的单引号,变成'bash -c "cd /tmp;"'。远程Shell解析时,会把外层单引号当作命令的一部分,导致引号匹配混乱,触发extra characters after close-quote错误。

可行的修正方案

方案1:适配Expect的转义规则,去掉外层单引号

直接用转义双引号包裹bash -c的参数,避免嵌套单引号带来的解析冲突:

ssh_param="-t ${scp_user}${_machine}  bash -c \"cd /tmp;\""

方案2:用Expect大括号保护复杂命令

如果需要执行包含环境变量的多段命令,用Expect的{}大括号包裹整段远程命令,避免频繁转义:

set ssh_param "-t ${scp_user}${_machine}  {bash -c \"cd /tmp; export TEST_VAR=foo; echo \$TEST_VAR\"}"

注意:大括号内部的变量引用(比如$TEST_VAR)需要加反斜杠转义,防止被本地Expect提前解析。

为什么去掉bash -c后能正常运行

当你改成"-t ${scp_user}${_machine} \"cd /tmp;\""时,传给SSH的命令是单纯的cd /tmp;,没有嵌套的引号结构,远程Shell不需要处理复杂的引号解析,因此可以正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:33:22