我已经被这个问题困扰了好几天了。
任务是连接到 sftp 服务器,迭代文件列表以 1.从sftp获取文件 2. 在本地执行一些文件操作,然后转到列表中的下一个文件。
这将是我的最小示例:
set filelist_path filelist.txt
proc slurp {file} {
set fh [open $file r]
set ret [read $fh]
close $fh
return $ret
}
set filelist [slurp $filelist_path]
set rundir [file normalize [file dirname .]]
### Start connection to ftp server
spawn sftp ${user}@${host}
expect "Password:"
send "$pass\r"
### Download and manipulate files in the list
foreach item $filelist {
expect "sftp>"
send_user "Processing $item : \n"
set filedir [file dirname ${item}]
set outdir ${rundir}/tmp${filedir}
puts [exec mkdir -p $outdir]
send "lcd $outdir \r"
send "get -p /data'${item}'\r"
send "lcd $rundir \r"
puts [exec <some cmd>]
puts [exec rm -r ./tmp]
}
send "quit\r"
expect eof
我的问题是,本地操作永远不会执行,或者迭代不会等待操作完成。 我尝试使用“期望“sftp>””命令并添加一些“交互”语句来查看发生了什么,但没有成功。
问题是您在处理文件之前没有等待
send
命令完成。移动文件需要花费时间,即使是很小的文件。最简单的方法是 expect "sftp>"
after 每个命令你 send
,即使是微不足道的命令。这是您验证其他程序是否已完成其正在执行的操作的方式。
并将第一个移出循环;将其视为连接设置的一部分。
我倾向于编写一个程序来发送命令并等待它完成。然后还可以以系统的方式检查错误情况(并且
expect
为您提供了这样做的工具)。毕竟,错误是编程变得更加复杂的地方......