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

使用Ruby实现FTP交互时脚本无法读取输出且挂起的问题排查

解决Ruby脚本调用FTP时无法读取输出、发送命令后挂起的问题

问题根源

  1. FTP交互时序错误:脚本批量发送所有命令,但FTP是交互式程序,必须等待它返回ftp>提示符后才能发送下一个命令,直接批量发送会导致命令在FTP未就绪时被提交,引发阻塞。
  2. 输出缓冲机制问题:FTP默认可能使用全缓冲而非行缓冲,导致stdout.each无法及时捕获输出,读取线程一直处于等待状态。
  3. 缺少响应同步逻辑:没有等待单条命令的响应完成就发送下一条,导致交互流程混乱。

修正后的脚本

require 'open3'

# 定义要发送的FTP命令
commands = [
  'ascii',
  'quote site filetype=jes',
  'put amblist.jcl',
  'dir',
  'quit' # 必须添加退出命令,避免FTP进程残留
]

user_id = 'mikes01'.downcase
# 加入-inv参数:-n禁止自动登录,-i关闭交互确认,-v开启 verbose模式输出所有响应
program_command = "ftp -inv ftp://#{user_id}:mypwd@bigiron"

captured_results = []
pattern = /你的目标匹配正则/ # 替换为你需要捕获的特定格式正则表达式

Open3.popen2e(program_command) do |stdin, stdout_err, wait_thread|
  # 后台线程读取并处理FTP输出,捕获匹配结果
  reader_thread = Thread.new do
    stdout_err.each_line do |line|
      puts line.chomp # 实时打印FTP响应
      # 扫描并保存匹配内容
      matches = line.scan(pattern)
      captured_results.concat(matches) unless matches.empty?
    end
  end

  # 等待FTP初始化完成,直到出现ftp>提示符
  loop do
    line = stdout_err.readline
    puts line.chomp
    break if line.include?('ftp>')
  end

  # 逐个发送命令,确保每条命令执行完成后再发下一条
  commands.each do |cmd|
    puts ">>> 发送命令: #{cmd}"
    stdin.puts cmd
    stdin.flush # 强制刷新输入缓冲区,确保命令立即发送

    # 等待当前命令执行完成,直到再次出现ftp>提示符
    loop do
      line = stdout_err.readline
      puts line.chomp
      break if line.include?('ftp>')
    end
  end

  stdin.close
  reader_thread.join # 等待读取线程处理完所有输出
  wait_thread.value # 获取FTP进程的退出状态
end

# 对捕获的结果进行后续计算或处理
puts "\n捕获到的匹配结果:"
p captured_results
# 在这里添加你的计算逻辑

关键改动说明

  • FTP参数优化:-inv参数解决自动登录冲突、交互阻塞问题,同时确保所有响应都能被捕获
  • 合并输出流:用popen2e替代popen2,将标准输出和错误输出合并,避免遗漏关键反馈
  • 时序同步:通过等待ftp>提示符,确保FTP在就绪状态下接收命令,避免提前发送导致的阻塞
  • 显式刷新缓冲区:stdin.flush确保命令立即发送到FTP进程,不会因缓冲延迟发送
  • 强制退出逻辑:添加quit命令,确保FTP执行完所有操作后正常退出,避免进程残留

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:22:44