mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/open3.rb (Open3.pipeline_start): return an array of threads if a
block is not given. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20618 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b314ab3e44
commit
3266ec1658
3 changed files with 112 additions and 20 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Thu Dec 11 02:23:51 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* lib/open3.rb (Open3.pipeline_start): return an array of threads if a
|
||||||
|
block is not given.
|
||||||
|
|
||||||
Thu Dec 11 01:48:00 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Thu Dec 11 01:48:00 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* ext/bigdecimal/bigdecimal.c (BigDecimal_round): should be round
|
* ext/bigdecimal/bigdecimal.c (BigDecimal_round): should be round
|
||||||
|
|
118
lib/open3.rb
118
lib/open3.rb
|
@ -11,6 +11,8 @@
|
||||||
#
|
#
|
||||||
# Open3 grants you access to stdin, stdout, stderr and a thread to wait the
|
# Open3 grants you access to stdin, stdout, stderr and a thread to wait the
|
||||||
# child process when running another program.
|
# child process when running another program.
|
||||||
|
# You can specify various attributes, redirections, current directory, etc., of
|
||||||
|
# the program as Process.spawn.
|
||||||
#
|
#
|
||||||
# - Open3.popen3 : pipes for stdin, stdout, stderr
|
# - Open3.popen3 : pipes for stdin, stdout, stderr
|
||||||
# - Open3.popen2 : pipes for stdin, stdout
|
# - Open3.popen2 : pipes for stdin, stdout
|
||||||
|
@ -41,7 +43,7 @@ module Open3
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# Non-block form:
|
# Non-block form:
|
||||||
#
|
#
|
||||||
# stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts])
|
# stdin, stdout, stderr, wait_thr = Open3.popen3([env,] cmd... [, opts])
|
||||||
# pid = wait_thr[:pid] # pid of the started process.
|
# pid = wait_thr[:pid] # pid of the started process.
|
||||||
# ...
|
# ...
|
||||||
|
@ -50,14 +52,14 @@ module Open3
|
||||||
# stderr.close
|
# stderr.close
|
||||||
# exit_status = wait_thr.value # Process::Status object returned.
|
# exit_status = wait_thr.value # Process::Status object returned.
|
||||||
#
|
#
|
||||||
# The parameters +cmd...+ is passed to Kernel#spawn.
|
# The parameters +cmd...+ is passed to Process.spawn.
|
||||||
# So a commandline string and list of argument strings can be accepted as follows.
|
# So a commandline string and list of argument strings can be accepted as follows.
|
||||||
#
|
#
|
||||||
# Open3.popen3("echo a") {|i, o, e, t| ... }
|
# Open3.popen3("echo a") {|i, o, e, t| ... }
|
||||||
# Open3.popen3("echo", "a") {|i, o, e, t| ... }
|
# Open3.popen3("echo", "a") {|i, o, e, t| ... }
|
||||||
# Open3.popen3(["echo", "argv0"], "a") {|i, o, e, t| ... }
|
# Open3.popen3(["echo", "argv0"], "a") {|i, o, e, t| ... }
|
||||||
#
|
#
|
||||||
# If the last parameter, opts, is a Hash, it is recognized as an option for Kernel#spawn.
|
# If the last parameter, opts, is a Hash, it is recognized as an option for Process.spawn.
|
||||||
#
|
#
|
||||||
# Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t|
|
# Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t|
|
||||||
# p o.read.chomp #=> "/"
|
# p o.read.chomp #=> "/"
|
||||||
|
@ -101,12 +103,14 @@ module Open3
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# Non-block form:
|
# Non-block form:
|
||||||
#
|
#
|
||||||
# stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts])
|
# stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts])
|
||||||
# ...
|
# ...
|
||||||
# stdin.close # stdin and stdout should be closed explicitly in this form.
|
# stdin.close # stdin and stdout should be closed explicitly in this form.
|
||||||
# stdout.close
|
# stdout.close
|
||||||
#
|
#
|
||||||
|
# See Process.spawn for the optional hash arguments _env_ and _opts_.
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# Open3.popen2("wc -c") {|i,o,t|
|
# Open3.popen2("wc -c") {|i,o,t|
|
||||||
|
@ -115,14 +119,14 @@ module Open3
|
||||||
# p o.gets #=> "42\n"
|
# p o.gets #=> "42\n"
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# Open3.popen2("bc -q") {|i,o,t|
|
# Open3.popen2("bc -q") {|i,o,t|
|
||||||
# i.puts "obase=13"
|
# i.puts "obase=13"
|
||||||
# i.puts "6 * 9"
|
# i.puts "6 * 9"
|
||||||
# p o.gets #=> "42\n"
|
# p o.gets #=> "42\n"
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# Open3.popen2("dc") {|i,o,t|
|
# Open3.popen2("dc") {|i,o,t|
|
||||||
# i.print "42P"
|
# i.print "42P"
|
||||||
# i.close
|
# i.close
|
||||||
# p o.read #=> "*"
|
# p o.read #=> "*"
|
||||||
# }
|
# }
|
||||||
|
@ -157,12 +161,14 @@ module Open3
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# Non-block form:
|
# Non-block form:
|
||||||
#
|
#
|
||||||
# stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts])
|
# stdin, stdout_and_stderr, wait_thr = Open3.popen2e([env,] cmd... [, opts])
|
||||||
# ...
|
# ...
|
||||||
# stdin.close # stdin and stdout_and_stderr should be closed explicitly in this form.
|
# stdin.close # stdin and stdout_and_stderr should be closed explicitly in this form.
|
||||||
# stdout_and_stderr.close
|
# stdout_and_stderr.close
|
||||||
#
|
#
|
||||||
|
# See Process.spawn for the optional hash arguments _env_ and _opts_.
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
# # check gcc warnings
|
# # check gcc warnings
|
||||||
# source = "foo.c"
|
# source = "foo.c"
|
||||||
|
@ -216,7 +222,8 @@ module Open3
|
||||||
#
|
#
|
||||||
# stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts])
|
# stdout_str, stderr_str, status = Open3.capture3([env,] cmd... [, opts])
|
||||||
#
|
#
|
||||||
# The arguments cmd and opts are passed to Open3.popen3 except opts[:stdin_data].
|
# The arguments env, cmd and opts are passed to Open3.popen3 except
|
||||||
|
# opts[:stdin_data] and opts[:stdin_data]. See Process.spawn.
|
||||||
#
|
#
|
||||||
# If opts[:stdin_data] is specified, it is sent to the command's standard input.
|
# If opts[:stdin_data] is specified, it is sent to the command's standard input.
|
||||||
#
|
#
|
||||||
|
@ -279,7 +286,8 @@ module Open3
|
||||||
#
|
#
|
||||||
# stdout_str, status = Open3.capture2([env,] cmd... [, opts])
|
# stdout_str, status = Open3.capture2([env,] cmd... [, opts])
|
||||||
#
|
#
|
||||||
# The arguments cmd and opts are passed to Open3.popen2 except opts[:stdin_data].
|
# The arguments env, cmd and opts are passed to Open3.popen3 except
|
||||||
|
# opts[:stdin_data] and opts[:stdin_data]. See Process.spawn.
|
||||||
#
|
#
|
||||||
# If opts[:stdin_data] is specified, it is sent to the command's standard input.
|
# If opts[:stdin_data] is specified, it is sent to the command's standard input.
|
||||||
#
|
#
|
||||||
|
@ -288,7 +296,7 @@ module Open3
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# # factor is a command for integer factorization.
|
# # factor is a command for integer factorization.
|
||||||
# o, s = Open3.capture2("factor", :stdin_data=>"42")
|
# o, s = Open3.capture2("factor", :stdin_data=>"42")
|
||||||
# p o #=> "42: 2 3 7\n"
|
# p o #=> "42: 2 3 7\n"
|
||||||
#
|
#
|
||||||
# # generate x**2 graph in png using gnuplot.
|
# # generate x**2 graph in png using gnuplot.
|
||||||
|
@ -296,12 +304,12 @@ module Open3
|
||||||
# set terminal png
|
# set terminal png
|
||||||
# plot x**2, "-" with lines
|
# plot x**2, "-" with lines
|
||||||
# 1 14
|
# 1 14
|
||||||
# 2 1
|
# 2 1
|
||||||
# 3 8
|
# 3 8
|
||||||
# 4 5
|
# 4 5
|
||||||
# e
|
# e
|
||||||
# End
|
# End
|
||||||
# image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true)
|
# image, s = Open3.capture2("gnuplot", :stdin_data=>gnuplot_commands, :binmode=>true)
|
||||||
#
|
#
|
||||||
def capture2(*cmd, &block)
|
def capture2(*cmd, &block)
|
||||||
if Hash === cmd.last
|
if Hash === cmd.last
|
||||||
|
@ -330,7 +338,8 @@ module Open3
|
||||||
#
|
#
|
||||||
# stdout_and_stderr_str, status = Open3.capture2e([env,] cmd... [, opts])
|
# stdout_and_stderr_str, status = Open3.capture2e([env,] cmd... [, opts])
|
||||||
#
|
#
|
||||||
# The arguments cmd and opts are passed to Open3.popen2e except opts[:stdin_data].
|
# The arguments env, cmd and opts are passed to Open3.popen3 except
|
||||||
|
# opts[:stdin_data] and opts[:stdin_data]. See Process.spawn.
|
||||||
#
|
#
|
||||||
# If opts[:stdin_data] is specified, it is sent to the command's standard input.
|
# If opts[:stdin_data] is specified, it is sent to the command's standard input.
|
||||||
#
|
#
|
||||||
|
@ -377,9 +386,17 @@ module Open3
|
||||||
# last_stdout.close
|
# last_stdout.close
|
||||||
#
|
#
|
||||||
# Each cmd is a string or an array.
|
# Each cmd is a string or an array.
|
||||||
# If it is an array, the elements are passed to Kernel#spawn.
|
# If it is an array, the elements are passed to Process.spawn.
|
||||||
#
|
#
|
||||||
# The option to pass Kernel#spawn is constructed by merging
|
# cmd:
|
||||||
|
# commandline command line string which is passed to a shell
|
||||||
|
# [env, commandline, opts] command line string which is passed to a shell
|
||||||
|
# [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
|
||||||
|
# [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
|
||||||
|
#
|
||||||
|
# Note that env and opts are optional, as Process.spawn.
|
||||||
|
#
|
||||||
|
# The option to pass Process.spawn is constructed by merging
|
||||||
# +opts+, the last hash element of the array and
|
# +opts+, the last hash element of the array and
|
||||||
# specification for the pipe between each commands.
|
# specification for the pipe between each commands.
|
||||||
#
|
#
|
||||||
|
@ -427,6 +444,17 @@ module Open3
|
||||||
# ...
|
# ...
|
||||||
# last_stdout.close
|
# last_stdout.close
|
||||||
#
|
#
|
||||||
|
# Each cmd is a string or an array.
|
||||||
|
# If it is an array, the elements are passed to Process.spawn.
|
||||||
|
#
|
||||||
|
# cmd:
|
||||||
|
# commandline command line string which is passed to a shell
|
||||||
|
# [env, commandline, opts] command line string which is passed to a shell
|
||||||
|
# [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
|
||||||
|
# [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
|
||||||
|
#
|
||||||
|
# Note that env and opts are optional, as Process.spawn.
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# Open3.pipeline_r("zcat /var/log/apache2/access.log.*.gz",
|
# Open3.pipeline_r("zcat /var/log/apache2/access.log.*.gz",
|
||||||
|
@ -468,10 +496,21 @@ module Open3
|
||||||
# ...
|
# ...
|
||||||
# first_stdin.close
|
# first_stdin.close
|
||||||
#
|
#
|
||||||
|
# Each cmd is a string or an array.
|
||||||
|
# If it is an array, the elements are passed to Process.spawn.
|
||||||
|
#
|
||||||
|
# cmd:
|
||||||
|
# commandline command line string which is passed to a shell
|
||||||
|
# [env, commandline, opts] command line string which is passed to a shell
|
||||||
|
# [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
|
||||||
|
# [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
|
||||||
|
#
|
||||||
|
# Note that env and opts are optional, as Process.spawn.
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# Open3.pipeline_w("bzip2 -c", :out=>"/tmp/hello.bz2") {|w, ts|
|
# Open3.pipeline_w("bzip2 -c", :out=>"/tmp/hello.bz2") {|w, ts|
|
||||||
# w.puts "hello"
|
# w.puts "hello"
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
def pipeline_w(*cmds, &block)
|
def pipeline_w(*cmds, &block)
|
||||||
|
@ -500,16 +539,39 @@ module Open3
|
||||||
# wait_threads = Open3.pipeline_start(cmd1, cmd2, ... [, opts])
|
# wait_threads = Open3.pipeline_start(cmd1, cmd2, ... [, opts])
|
||||||
# ...
|
# ...
|
||||||
#
|
#
|
||||||
|
# Each cmd is a string or an array.
|
||||||
|
# If it is an array, the elements are passed to Process.spawn.
|
||||||
|
#
|
||||||
|
# cmd:
|
||||||
|
# commandline command line string which is passed to a shell
|
||||||
|
# [env, commandline, opts] command line string which is passed to a shell
|
||||||
|
# [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
|
||||||
|
# [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
|
||||||
|
#
|
||||||
|
# Note that env and opts are optional, as Process.spawn.
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# # run xeyes in 10 seconds.
|
# # run xeyes in 10 seconds.
|
||||||
# Open3.pipeline_start("xeyes") {|ts|
|
# Open3.pipeline_start("xeyes") {|ts|
|
||||||
# sleep 10
|
# sleep 10
|
||||||
# t = ts[0]
|
# t = ts[0]
|
||||||
# Process.kill("TERM", t.pid)
|
# Process.kill("TERM", t.pid)
|
||||||
# p t.value #=> #<Process::Status: pid 911 SIGTERM (signal 15)>
|
# p t.value #=> #<Process::Status: pid 911 SIGTERM (signal 15)>
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
|
# # convert pdf to ps and send it to a printer.
|
||||||
|
# # collect error message of pdftops and lpr.
|
||||||
|
# pdf_file = "paper.pdf"
|
||||||
|
# printer = "printer-name"
|
||||||
|
# err_r, err_w = IO.pipe
|
||||||
|
# Open3.pipeline_start(["pdftops", pdf_file, "-"],
|
||||||
|
# ["lpr", "-P#{printer}"],
|
||||||
|
# :err=>err_w) {|ts|
|
||||||
|
# err_w.close
|
||||||
|
# p err_r.read # error messages of pdftops and lpr.
|
||||||
|
# }
|
||||||
|
#
|
||||||
def pipeline_start(*cmds, &block)
|
def pipeline_start(*cmds, &block)
|
||||||
if Hash === cmds.last
|
if Hash === cmds.last
|
||||||
opts = cmds.pop.dup
|
opts = cmds.pop.dup
|
||||||
|
@ -517,7 +579,12 @@ module Open3
|
||||||
opts = {}
|
opts = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline_run(cmds, opts, [], [], &block)
|
if block
|
||||||
|
pipeline_run(cmds, opts, [], [], &block)
|
||||||
|
else
|
||||||
|
ts, = pipeline_run(cmds, opts, [], [])
|
||||||
|
ts
|
||||||
|
end
|
||||||
end
|
end
|
||||||
module_function :pipeline_start
|
module_function :pipeline_start
|
||||||
|
|
||||||
|
@ -528,10 +595,21 @@ module Open3
|
||||||
#
|
#
|
||||||
# status_list = Open3.pipeline(cmd1, cmd2, ... [, opts])
|
# status_list = Open3.pipeline(cmd1, cmd2, ... [, opts])
|
||||||
#
|
#
|
||||||
|
# Each cmd is a string or an array.
|
||||||
|
# If it is an array, the elements are passed to Process.spawn.
|
||||||
|
#
|
||||||
|
# cmd:
|
||||||
|
# commandline command line string which is passed to a shell
|
||||||
|
# [env, commandline, opts] command line string which is passed to a shell
|
||||||
|
# [env, cmdname, arg1, ..., opts] command name and one or more arguments (no shell)
|
||||||
|
# [env, [cmdname, argv0], arg1, ..., opts] command name and arguments including argv[0] (no shell)
|
||||||
|
#
|
||||||
|
# Note that env and opts are optional, as Process.spawn.
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# fname = "/usr/share/man/man1/ruby.1.gz"
|
# fname = "/usr/share/man/man1/ruby.1.gz"
|
||||||
# p Open3.pipeline(["zcat", fname], "nroff -man", "less")
|
# p Open3.pipeline(["zcat", fname], "nroff -man", "less")
|
||||||
# #=> [#<Process::Status: pid 11817 exit 0>,
|
# #=> [#<Process::Status: pid 11817 exit 0>,
|
||||||
# # #<Process::Status: pid 11820 exit 0>,
|
# # #<Process::Status: pid 11820 exit 0>,
|
||||||
# # #<Process::Status: pid 11828 exit 0>]
|
# # #<Process::Status: pid 11828 exit 0>]
|
||||||
|
|
|
@ -214,6 +214,15 @@ class TestOpen3 < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_pipeline_start_noblock
|
||||||
|
ts = Open3.pipeline_start([RUBY, '-e', ''])
|
||||||
|
assert_kind_of(Array, ts)
|
||||||
|
assert_equal(1, ts.length)
|
||||||
|
ts.each {|t| assert_kind_of(Thread, t) }
|
||||||
|
t = ts[0]
|
||||||
|
assert(t.value.success?)
|
||||||
|
end
|
||||||
|
|
||||||
def test_pipeline
|
def test_pipeline
|
||||||
command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
|
command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
|
||||||
str = 'ttftff'
|
str = 'ttftff'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue