加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

什么是Ruby中的可移植方式,以便在您尝试从中读取时检查STDIN将阻

发布时间:2020-12-17 02:01:17 所属栏目:百科 来源:网络整理
导读:我想知道是否有一种可移植的方法来检查 Ruby脚本是否会阻止它尝试从STDIN读取.以下是适用于Unix(和Cygwin)但不适用于本机Win32的方法. (它基于我很久以前学过的Perl方法.) $cat read-stdin.rb #! /usr/bin/ruby# test of reading from STDINrequire 'fcntl'#
我想知道是否有一种可移植的方法来检查 Ruby脚本是否会阻止它尝试从STDIN读取.以下是适用于Unix(和Cygwin)但不适用于本机Win32的方法. (它基于我很久以前学过的Perl方法.)

$cat read-stdin.rb

#! /usr/bin/ruby
# test of reading from STDIN

require 'fcntl'

# Trace info on input objects
$stdout.sync=TRUE if $DEBUG         # make sure standard output and error synchronized
$stderr.print "ARGV=#{ARGV}n" if $DEBUG
$stderr.print "ARGF=#{ARGF}n" if $DEBUG

# See if input available,showing usage statement if not
blocking_stdin = FALSE
if (defined? Fcntl::F_GETFL) then
  $stderr.print "F_GETFL=#{Fcntl::F_GETFL} O_RDWR=#{Fcntl::O_RDWR}n" if $DEBUG
  flags = STDIN.fcntl(Fcntl::F_GETFL,0) 
  $stderr.print "flags=#{flags}n" if $DEBUG
  blocking_stdin = TRUE if ((flags & Fcntl::O_RDWR) == Fcntl::O_RDWR)
  $stderr.print "blocking_stdin=#{blocking_stdin}n" if $DEBUG
end
if (blocking_stdin && (ARGV.length == 0)) then
  $stderr.print "usage: #{$0} [-]n"
  Process.exit
end

# Read input and output it
$stderr.print "Input:n" if $DEBUG
input_text = ARGF.read()
$stderr.print "Output:n" if $DEBUG
print "#{input_text}n"

这是没有调试的交互:

$grep -v DEBUG read-stdin.rb >| /tmp/simple-read-stdin.rb

$echo hey | ruby /tmp/simple-read-stdin.rb
hey

$ruby /tmp/simple-read-stdin.rb
usage: /tmp/simple-read-stdin.rb [-]

这是与调试的交互:

$echo hey | ruby -d read-stdin.rb
ARGV=
ARGF=ARGF
F_GETFL=3 O_RDWR=2
flags=65536
blocking_stdin=false
Input:
Output:
hey

$ruby -d read-stdin.rb
ARGV=
ARGF=ARGF
F_GETFL=3 O_RDWR=2
flags=98306
blocking_stdin=true
usage: read-stdin.rb [-]

解决方法

我不知道它是否普遍可移植,我也不知道它是否被认为是一个好主意(阻塞不是一个糟糕的概念)但IO中有一个 non-blocking read method.你可以像这样使用它:

chunk = nil

begin
  chunk = STDIN.read_nonblock(4096)
rescue Errno::EAGAIN
  # Handle the case if it would block
  chunk = 'nothing there...'
end

虽然,我认为如果没有指定像IO这样的缓冲区大小就行不通,它就会失败,但是通过使用循环解决这个问题应该很容易.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读