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

如何在expect脚本中获取spawn启动的scp进程返回码

expect获取spawn启动的scp进程返回码实现方案

核心原理:expect中spawn拉起的子进程退出状态,需要通过wait命令捕获后提取,你原有脚本存在几处语法、逻辑问题会导致拿不到返回码,需要一并修正:

  • 关键字大小写错误:expect内置命令spawn/expect均为小写,原脚本大写开头的Spawn/Expect会直接执行报错;另外bash中定义的密码变量是Password,后续引用写为$password大小写不匹配,会读不到密码值
  • 引号嵌套错误:原脚本在bash双引号包裹的expect代码内,直接使用双引号写匹配规则"*password:*",会被bash提前截断字符串,导致expect语法解析失败
  • 逻辑缺失:发送密码后使用interact会直接将控制台控制权交还给用户,不会自动等待scp执行完成,也没有配置进程状态捕获逻辑
  • shebang写法错误:脚本开头解释器路径少了!,正确写法为#!/bin/bash

修正后可直接运行的脚本

#!/bin/bash
Password=1234
expect -c "
# 关闭超时限制,避免大文件传输中途被expect默认超时机制中断
set timeout -1
spawn /usr/bin/scp -r /tmp/ss sus@servername:/var/tmp/
expect {
    \"*password:*\" {
        send \"$Password\r\"
        # 等待scp传输完成、连接断开,不要使用interact
        expect eof
    }
    eof {
        # 已配置免密登录时不会弹出密码提示,直接等待进程结束
    }
}
# 回收子进程资源,wait返回格式为 {pid spawn_id 退出类型 退出码}
set wait_result [wait]
set scp_exit_code [lindex \$wait_result 3]
# 将scp的退出码作为expect进程的退出码返回给外层bash
exit \$scp_exit_code
"

# 外层bash通过$?即可拿到scp的真实执行返回码
echo "scp执行返回码: $?"

关键说明

  • 返回码规则和scp原生规则完全一致:返回0代表传输成功,非0代表执行失败(常见原因包括认证失败、文件不存在、权限不足、网络中断、目标路径不可写等)
  • 提取返回码时取wait返回列表的第4个元素(tcl列表索引从0开始,所以索引值为3),该值就是spawn拉起的scp进程的真实退出码
  • 如果需要排查匹配问题,可以在expect代码开头加exp_internal 1开启调试日志,能看到完整的交互匹配、进程状态流转过程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:06:41