使用Expect脚本拷贝文件报错:send: spawn id exp6 not open
问题分析与解决办法
错误原因
- 你的脚本默认认为
cp命令会弹出?(y/n)?的确认提示,但实际场景中存在两种导致报错的情况:- 多数系统默认的
cp在覆盖文件时不会触发交互提示,只有手动添加-i参数,或系统给cp设置了alias cp='cp -i'别名时,才会出现确认提示。 - 如果
cp命令未触发交互,会直接执行完毕并退出进程,此时expect还在等待匹配提示,后续的send命令就会因spawn进程已关闭而报错。
- 多数系统默认的
修正后的脚本方案
根据需求分两种场景处理:
场景1:需要交互确认(覆盖时手动确认)
如果确实需要覆盖时弹出确认,需在cp命令中明确加-i参数,同时优化脚本逻辑处理进程提前结束的情况:
set src_file "/process/source" set dest_file "/process/destination" spawn /bin/cp -r -i $src_file $dest_file # 同时匹配确认提示和进程结束的情况 expect { "*?(y/n)?" { send "y\r" expect eof } eof { puts "cp命令未触发交互,已执行完成" } }
场景2:无需交互,直接完成拷贝
如果不需要交互确认,直接用shell命令即可,没必要用Expect:
cp -r /process/source /process/destination
如果必须嵌入到Expect流程中,可简化为:
set src_file "/process/source" set dest_file "/process/destination" spawn /bin/cp -r $src_file $dest_file expect eof
额外注意事项
- 避免别名干扰:脚本中调用
/bin/cp而非直接写cp,防止系统中cp的别名(比如cp -i)打乱预期行为。 - 权限检查:确保运行脚本的用户对
/process/source有读权限,对/process/destination有写权限,否则cp会直接报错退出,不会触发交互。
内容的提问来源于stack exchange,提问作者Jeniffer Lorena Guillen Castro
相关产品推荐
相关产品推荐

