【问题标题】:Why is IO.popen hanging on a valid command?为什么 IO.popen 挂在有效命令上?
【发布时间】:2011-11-28 21:59:00
【问题描述】:

我正在使用IO.popen 运行curl 命令(八位字节流POST)。我复制命令并在命令行上运行它,它可以工作。但是,使用 popen 在 Ruby 中运行它会导致流在我的服务器上意外结束,并且 Ruby 脚本只是挂起,curl 无休止地运行。

这就是我正在做的事情:

curl = "curl "
curl += "--cookie \"JSESSIONID=#{@sessionid}\" "
curl += "-H \"Content-type:application/octet-stream\" "
curl += "-X POST "
curl += "-o \"#{responseFile}\" "
curl += "--data-binary \"@#{filename}\" "
curl += "\"#{url}\""

puts "command: #{curl}"

IO.popen(curl, "r") { |out|
  out.readlines
}
# Script never makes it to here

我一定是在做一些傻事。这是什么?

Here is the stdout from curl.

我正在使用 Ruby 1.8.6

【问题讨论】:

  • 我将 stdout 和 stderr 都通过管道传输到一个文件,该文件是该 pastebin 链接的来源。
  • 是的,我的服务器无法读取流,因为它意外到达 eof,所以我收到了从服务器发回的错误消息。它优雅地失败了,但仍然失败了。
  • 您是否尝试过不同版本/发行版的 Ruby?
  • 为什么需要打开管道?试试`#{curl}`

标签: ruby curl stream popen


【解决方案1】:

popen 还为 curl 提供了一个管道来读取 来自,如下例所示:

$ echo -e 'foo\nbar\nzoo' | \
  ruby -e 'pipe = IO.popen("grep oo", "r") {|out| p out.readlines}'
["foo\n", "zoo\n"]

我猜 curl 也想从 stdin 向服务器 POST,没有任何东西来自那里,所以它会超时 30 秒。

【讨论】:

  • -data 参数的 man 信息(与 --data-binary 类似)意味着在参数前使用“@”会导致 curl 从文件而不是 stdin 发布。
【解决方案2】:

与其编写自己的轮子版本,不如利用许多用于 Ruby 的 gem 来做同样的事情?

我建议以 typhoeuscurb 作为起点。此外,内置的OpenURI 可以很好地满足大多数“get”类型的需求。

在 SO 上也有一个 useful thread 用于此帖子请求。

【讨论】:

  • 是的,我不知道。不幸的是,我的代码在缺少标准库的 Ruby 环境中运行……这实际上是我必须编写这个小块的全部原因。我过去使用过 RestClient 并取得了巨大的成功。
  • 但是,如果您可以在 Mac 上为 Ruby 1.8.5 编译标准 C 扩展(我尝试过但无法全部获得)或者找到一个不依赖任何 C 的 HTTP 库>1.8.5 的扩展或功能,请告诉我 =)
猜你喜欢
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 2016-04-21
相关资源
最近更新 更多