[#44713] パイプ経由コマンド実行? — "morita" <m-morita@...>
もりたと申します。お世話になります。
10 messages
2008/03/03
[#44714] Re: パイプ経由コマンド実行?
— Hidetoshi NAGAI <nagai@...>
2008/03/03
永井@知能.九工大です.
[#44716] Re: パイプ経由コマンド実行?
— "m-morita" <m-morita@...>
2008/03/03
もりた です。
[#44725] Set[Set[1]]==Set[Set[1]] は偽? — "5.5" <5.5@...>
5.5 です。
22 messages
2008/03/04
[#44726] Re: Set[Set[1]]==Set[Set[1]] は偽?
— "Ohto, Yasunori" <Yasunori.Ohto@...>
2008/03/05
大戸です。
[#44744] Re: Set[Set[1]]==Set[Set[1]] は偽?
— "5.5" <5.5@...>
2008/03/06
5.5 です。
[#44728] ダウンロードリンクが古い — Kouhei Yanagita <yanagi@...>
こんにちは。柳田です。
10 messages
2008/03/05
[#44745] [ANN] Rails勉強会@東京 第28回のお知らせ — "MOROHASHI Kyosuke" <moronatural@...>
各位
1 message
2008/03/07
[#44769] Ann: Ruby-1.9.0-1 Windowsインストーラパッケージ — arton <artonx@...>
artonです。
4 messages
2008/03/13
[#44773] PHPとの関数対照表 — "tadashi nagao" <tadashi.nagao@...>
長尾です。
7 messages
2008/03/14
[#44782] $stdin.rewind が exec した子プロセスに伝わらない? — SATOH Fumiyasu <fumiyas@...>
さとうふみやす @ OSS テクノロジです。
11 messages
2008/03/17
[#44783] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— Kazuhiro NISHIYAMA <zn@...>
2008/03/17
西山和広です。
[#44785] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— Nobuyoshi Nakada <nobu@...>
2008/03/17
なかだです。
[#44786] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— SATOH Fumiyasu <fumiyas@...>
2008/03/18
さとうふみやす @ OSS テクノロジです。
[#44787] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— Nobuyoshi Nakada <nobu@...>
2008/03/18
なかだです。
[#44788] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— SATOH Fumiyasu <fumiyas@...>
2008/03/18
さとうふみやす @ OSS テクノロジです。
[ruby-list:44788] Re: $stdin.rewind が exec した子プロセスに伝わらない?
From:
SATOH Fumiyasu <fumiyas@...>
Date:
2008-03-18 09:19:21 UTC
List:
ruby-list #44788
さとうふみやす @ OSS テクノロジです。
At Tue, 18 Mar 2008 17:56:03 +0900,
Nobuyoshi Nakada wrote:
> > ということで stdio を使っていないという Ruby 1.9 (1.9.0-1) で
> > 試したところ、期待通りの動作をしました。
> > 個人的にこの手の処理 (子プロセスとの IPC) は頻繁に利用するので、
> > Ruby 1.8 系列だと危なそうですね…。早く Ruby 1.9 が普及することを
> > 願ってます。(できれば協力もしたいのだけど、時間なさすぎ。)
>
> IO.popenではうまくいかないものでしょうか。
シェルを介したくないんですが、IO.popen でできましたっけ?
コマンドインジェクションの可能性とか、シェルのメタ文字を
エスケープとか、セキュリティの不安や不確実性を
対応したり考えるのが嫌なので。なので、Kernel#system も:
system([cmd, cmd], args)
としています。
あとは stdin だけでなく、 stderr も読みたいこともあります。
こんな感じ (某プログラムより抜粋):
def read_file(input)
## Copy the target file into the local filesystem because most
## of the filter commands require input file must be seekable.
input_tmp = Tempfile.new('chimera-filter')
input_tmp.unlink
super(input, input_tmp)
input_tmp.rewind
stdout_reader, stdout_writer = IO.pipe
stderr_reader, stderr_writer = IO.pipe
pid = Process.fork
unless pid
begin
$stdin.reopen(input_tmp)
input_tmp.close
$stdout.reopen(stdout_writer)
stdout_writer.close
stdout_reader.close
$stderr.reopen(stderr_writer)
stderr_writer.close
stderr_reader.close
ENV['PATH'] = @path if (@path)
Kernel.exec([@command, @arg0], *@args)
rescue Exception => e
$stderr.puts("#{$0}: ERROR: #{__FILE__}: exec failed: #{@command}: #{e}")
exit!(1)
end
end
stdout_writer.close
stderr_writer.close
text = String.new
stdout_reader_th = Thread.start do
if @read_filter
until stdout_reader.eof?
text << @read_filter.call(stdout_reader.read(@read_size))
end
else
until stdout_reader.eof?
text << stdout_reader.read(@read_size)
end
end
end
@error = nil
stderr_reader_th = Thread.start do
@error = stderr_reader.read
@error = nil if @error.empty?
end
begin
unless stdout_reader_th.join(@timeout)
Process.kill('TERM', pid)
unless stdout_reader_th.join(5)
Process.kill('KILL', pid)
stdout_reader_th.join
end
raise FilterCommandError.new("#{@command}: timeout (#{@timeout} sec)")
end
ensure
stderr_reader_th.join
Process.waitpid(pid)
end
if $?.signaled?
raise FilterCommandError.new("#{@command}: signaled: #{$?.termsig} (SIG#{Signal.list.index($?.termsig)})")
elsif $?.exitstatus != 0
raise FilterCommandError.new("#{@command}: exit status: #{$?.exitstatus}")
end
return text
end
我ながらうまく書けた (自画自賛 :-) と思っているんですが、
ダメ出しあるなら頂けると嬉しいです。> all
--
-- Name: SATOH Fumiyasu (fumiyas @ osstech co jp)
-- Business Home: http://www.OSSTech.co.jp/
-- Personal Home: http://www.SFO.jp/blog/