Module Open3 supports creating child processes with access to their $stdin, $stdout, and $stderr streams.
Whatâs Here¶ ↑Each of these methods executes a given command in a new process or subshell, or multiple commands in new processes and/or subshells:
Each of these methods executes a single command in a process or subshell, accepts a string for input to $stdin, and returns string output from $stdout, $stderr, or both:
Open3.capture2
: Executes the command; returns the string from $stdout.
Open3.capture2e
: Executes the command; returns the string from merged $stdout and $stderr.
Open3.capture3
: Executes the command; returns strings from $stdout and $stderr.
Each of these methods executes a single command in a process or subshell, and returns pipes for $stdin, $stdout, and/or $stderr:
Open3.popen2
: Executes the command; returns pipes for $stdin and $stdout.
Open3.popen2e
: Executes the command; returns pipes for $stdin and merged $stdout and $stderr.
Open3.popen3
: Executes the command; returns pipes for $stdin, $stdout, and $stderr.
Each of these methods executes one or more commands in processes and/or subshells, returns pipes for the first $stdin, the last $stdout, or both:
Open3.pipeline_r
: Returns a pipe for the last $stdout.
Open3.pipeline_rw
: Returns pipes for the first $stdin and the last $stdout.
Open3.pipeline_w
: Returns a pipe for the first $stdin.
Open3.pipeline_start
: Does not wait for processes to complete.
Open3.pipeline
: Waits for processes to complete.
Each of the methods above accepts:
An optional hash of environment variable names and values; see Execution Environment.
A required string argument that is a command_line
or exe_path
; see Argument command_line or exe_path.
An optional hash of execution options; see Execution Options.
def capture2(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2(*cmd, opts) {|i, o, t| if binmode i.binmode o.binmode end out_reader = Thread.new { o.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [out_reader.value, t.value] } end
Basically a wrapper for Open3.popen3
that:
Creates a child process, by calling Open3.popen3
with the given arguments (except for certain entries in hash options
; see below).
Returns as string stdout_s
the standard output of the child process.
Returns as status
a Process::Status
object that represents the exit status of the child process.
Returns the array [stdout_s, status]
:
stdout_s, status = Open3.capture2('echo "Foo"')
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Open3.popen3
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Open3.popen3
; see Execution Options.
The hash options
is given; two options have local effect in method Open3.capture2
:
If entry options[:stdin_data]
exists, the entry is removed and its string value is sent to the commandâs standard input:
Open3.capture2('tee', stdin_data: 'Foo')
If entry options[:binmode]
exists, the entry is removed and the internal streams are set to binary mode.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.capture2('if true; then echo "Foo"; fi') Open3.capture2('echo') Open3.capture2('date > date.tmp')
The command line may also contain arguments and options for the command:
Open3.capture2('echo "Foo"')
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.capture2('/usr/bin/date')
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture2('doesnt_exist')
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.capture2('echo', 'C #') Open3.capture2('echo', 'hello', 'world')Source
def capture2e(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2e(*cmd, opts) {|i, oe, t| if binmode i.binmode oe.binmode end outerr_reader = Thread.new { oe.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [outerr_reader.value, t.value] } end
Basically a wrapper for Open3.popen3
that:
Creates a child process, by calling Open3.popen3
with the given arguments (except for certain entries in hash options
; see below).
Returns as string stdout_and_stderr_s
the merged standard output and standard error of the child process.
Returns as status
a Process::Status
object that represents the exit status of the child process.
Returns the array [stdout_and_stderr_s, status]
:
stdout_and_stderr_s, status = Open3.capture2e('echo "Foo"')
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Open3.popen3
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Open3.popen3
; see Execution Options.
The hash options
is given; two options have local effect in method Open3.capture2e
:
If entry options[:stdin_data]
exists, the entry is removed and its string value is sent to the commandâs standard input:
Open3.capture2e('tee', stdin_data: 'Foo')
If entry options[:binmode]
exists, the entry is removed and the internal streams are set to binary mode.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.capture2e('if true; then echo "Foo"; fi') Open3.capture2e('echo') Open3.capture2e('date > date.tmp')
The command line may also contain arguments and options for the command:
Open3.capture2e('echo "Foo"')
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.capture2e('/usr/bin/date')
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture2e('doesnt_exist')
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.capture2e('echo', 'C #') Open3.capture2e('echo', 'hello', 'world')Source
def capture3(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) || '' binmode = opts.delete(:binmode) popen3(*cmd, opts) {|i, o, e, t| if binmode i.binmode o.binmode e.binmode end out_reader = Thread.new { o.read } err_reader = Thread.new { e.read } begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end i.close [out_reader.value, err_reader.value, t.value] } end
Basically a wrapper for Open3.popen3
that:
Creates a child process, by calling Open3.popen3
with the given arguments (except for certain entries in hash options
; see below).
Returns as strings stdout_s
and stderr_s
the standard output and standard error of the child process.
Returns as status
a Process::Status
object that represents the exit status of the child process.
Returns the array [stdout_s, stderr_s, status]
:
stdout_s, stderr_s, status = Open3.capture3('echo "Foo"')
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Open3.popen3
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Open3.popen3
; see Execution Options.
The hash options
is given; two options have local effect in method Open3.capture3
:
If entry options[:stdin_data]
exists, the entry is removed and its string value is sent to the commandâs standard input:
Open3.capture3('tee', stdin_data: 'Foo')
If entry options[:binmode]
exists, the entry is removed and the internal streams are set to binary mode.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.capture3('if true; then echo "Foo"; fi') Open3.capture3('echo') Open3.capture3('date > date.tmp')
The command line may also contain arguments and options for the command:
Open3.capture3('echo "Foo"')
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.capture3('/usr/bin/date')
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture3('doesnt_exist')
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.capture3('echo', 'C #') Open3.capture3('echo', 'hello', 'world')Source
def pipeline(*cmds) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end pipeline_run(cmds, opts, [], []) {|ts| ts.map(&:value) } end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the last child, to the callerâs stdout
.
Waits for the child processes to exit.
Returns an array of Process::Status
objects (one for each child).
Example:
wait_threads = Open3.pipeline('ls', 'grep R')
Output:
Rakefile README.md
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
â see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_r(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [out_w], [out_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the last child, to the callerâs stdout
.
The method does not wait for child processes to exit, so the caller must do so.
With no block given, returns a 2-element array containing:
The stdout
stream of the last child process.
An array of the wait threads for all of the child processes.
Example:
last_stdout, wait_threads = Open3.pipeline_r('ls', 'grep R') puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
Output:
Rakefile README.md
With a block given, calls the block with the stdout
stream of the last child process, and an array of the wait processes:
Open3.pipeline_r('ls', 'grep R') do |last_stdout, wait_threads| puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
Output:
Rakefile README.md
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_rw(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the first child, from the callerâs stdin
, or, for the last child, to the callerâs stdout
.
The method does not wait for child processes to exit, so the caller must do so.
With no block given, returns a 3-element array containing:
The stdin
stream of the first child process.
The stdout
stream of the last child process.
An array of the wait threads for all of the child processes.
Example:
first_stdin, last_stdout, wait_threads = Open3.pipeline_rw('sort', 'cat -n') first_stdin.puts("foo\nbar\nbaz") first_stdin.close puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
Output:
1 bar 2 baz 3 foo
With a block given, calls the block with the stdin
stream of the first child, the stdout
stream of the last child, and an array of the wait processes:
Open3.pipeline_rw('sort', 'cat -n') do |first_stdin, last_stdout, wait_threads| first_stdin.puts "foo\nbar\nbaz" first_stdin.close puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
Output:
1 bar 2 baz 3 foo
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_start(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end if block pipeline_run(cmds, opts, [], [], &block) else ts, = pipeline_run(cmds, opts, [], []) ts end end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Does not wait for child processes to exit.
With no block given, returns an array of the wait threads for all of the child processes.
Example:
wait_threads = Open3.pipeline_start('ls', 'grep R') wait_threads.each do |wait_thread| wait_thread.join end
Output:
Rakefile README.md
With a block given, calls the block with an array of the wait processes:
Open3.pipeline_start('ls', 'grep R') do |wait_threads| wait_threads.each do |wait_thread| wait_thread.join end end
Output:
Rakefile README.md
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_w(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true pipeline_run(cmds, opts, [in_r], [in_w], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the first child, pipes the callerâs stdout
to the childâs stdin
.
The method does not wait for child processes to exit, so the caller must do so.
With no block given, returns a 2-element array containing:
The stdin
stream of the first child process.
An array of the wait threads for all of the child processes.
Example:
first_stdin, wait_threads = Open3.pipeline_w('sort', 'cat -n') first_stdin.puts("foo\nbar\nbaz") first_stdin.close wait_threads.each do |wait_thread| wait_thread.join end
Output:
1 bar 2 baz 3 foo
With a block given, calls the block with the stdin
stream of the first child process, and an array of the wait processes:
Open3.pipeline_w('sort', 'cat -n') do |first_stdin, wait_threads| first_stdin.puts("foo\nbar\nbaz") first_stdin.close wait_threads.each do |wait_thread| wait_thread.join end end
Output:
1 bar 2 baz 3 foo
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef popen2(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process, by calling Process.spawn
with the given arguments.
Creates streams stdin
and stdout
, which are the standard input and standard output streams in the child process.
Creates thread wait_thread
that waits for the child process to exit; the thread has method pid
, which returns the process ID of the child process.
With no block given, returns the array [stdin, stdout, wait_thread]
. The caller should close each of the two returned streams.
stdin, stdout, wait_thread = Open3.popen2('echo') stdin.close stdout.close wait_thread.pid wait_thread.value
With a block given, calls the block with the three variables (two streams and the wait thread) and returns the blockâs return value. The caller need not close the streams:
Open3.popen2('echo') do |stdin, stdout, wait_thread| p stdin p stdout p wait_thread p wait_thread.pid p wait_thread.value end
Output:
2263636
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Process.spawn
; see Execution Options.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.popen2('if true; then echo "Foo"; fi') {|*args| p args } Open3.popen2('echo') {|*args| p args } Open3.popen2('date > date.tmp') {|*args| p args }
Output (similar for each call above):
The command line may also contain arguments and options for the command:
Open3.popen2('echo "Foo"') { |i, o, t| o.gets } "Foo\n"
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.popen2('/usr/bin/date') { |i, o, t| o.gets }
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen2('doesnt_exist') { |i, o, t| o.gets }
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.popen2('echo', 'C #') { |i, o, t| o.gets } Open3.popen2('echo', 'hello', 'world') { |i, o, t| o.gets }
Related:
Open3.popen2e
: Makes the standard input and the merge of the standard output and standard error streams of the child process available as separate streams.
Open3.popen3
: Makes the standard input, standard output, and standard error streams of the child process available as separate streams.
def popen2e(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[[:out, :err]] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) ensure if block in_r.close in_w.close out_r.close out_w.close end end
Basically a wrapper for Process.spawn
that:
Creates a child process, by calling Process.spawn
with the given arguments.
Creates streams stdin
, stdout_and_stderr
, which are the standard input and the merge of the standard output and standard error streams in the child process.
Creates thread wait_thread
that waits for the child process to exit; the thread has method pid
, which returns the process ID of the child process.
With no block given, returns the array [stdin, stdout_and_stderr, wait_thread]
. The caller should close each of the two returned streams.
stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo') stdin.close stdout_and_stderr.close wait_thread.pid wait_thread.value
With a block given, calls the block with the three variables (two streams and the wait thread) and returns the blockâs return value. The caller need not close the streams:
Open3.popen2e('echo') do |stdin, stdout_and_stderr, wait_thread| p stdin p stdout_and_stderr p wait_thread p wait_thread.pid p wait_thread.value end
Output:
2274763
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Process.spawn
; see Execution Options.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.popen2e('if true; then echo "Foo"; fi') {|*args| p args } Open3.popen2e('echo') {|*args| p args } Open3.popen2e('date > date.tmp') {|*args| p args }
Output (similar for each call above):
The command line may also contain arguments and options for the command:
Open3.popen2e('echo "Foo"') { |i, o_and_e, t| o_and_e.gets } "Foo\n"
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.popen2e('/usr/bin/date') { |i, o_and_e, t| o_and_e.gets }
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen2e('doesnt_exist') { |i, o_and_e, t| o_and_e.gets }
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.popen2e('echo', 'C #') { |i, o_and_e, t| o_and_e.gets } Open3.popen2e('echo', 'hello', 'world') { |i, o_and_e, t| o_and_e.gets }
Related:
Open3.popen2
: Makes the standard input and standard output streams of the child process available as separate streams, with no access to the standard error stream.
Open3.popen3
: Makes the standard input, standard output, and standard error streams of the child process available as separate streams.
def popen3(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w err_r, err_w = IO.pipe opts[:err] = err_w popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process, by calling Process.spawn
with the given arguments.
Creates streams stdin
, stdout
, and stderr
, which are the standard input, standard output, and standard error streams in the child process.
Creates thread wait_thread
that waits for the child process to exit; the thread has method pid
, which returns the process ID of the child process.
With no block given, returns the array [stdin, stdout, stderr, wait_thread]
. The caller should close each of the three returned streams.
stdin, stdout, stderr, wait_thread = Open3.popen3('echo') stdin.close stdout.close stderr.close wait_thread.pid wait_thread.value
With a block given, calls the block with the four variables (three streams and the wait thread) and returns the blockâs return value. The caller need not close the streams:
Open3.popen3('echo') do |stdin, stdout, stderr, wait_thread| p stdin p stdout p stderr p wait_thread p wait_thread.pid p wait_thread.value end
Output:
2211047
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Process.spawn
; see Execution Options.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.popen3('if true; then echo "Foo"; fi') {|*args| p args } Open3.popen3('echo') {|*args| p args } Open3.popen3('date > date.tmp') {|*args| p args }
Output (similar for each call above):
[#<IO:(closed)>, #<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f58d52f28c8 dead>]
The command line may also contain arguments and options for the command:
Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets } "Foo\n"
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.popen3('/usr/bin/date') { |i, o, e, t| o.gets }
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets }
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.popen3('echo', 'C #') { |i, o, e, t| o.gets } Open3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets }
Take care to avoid deadlocks. Output streams stdout
and stderr
have fixed-size buffers, so reading extensively from one but not the other can cause a deadlock when the unread buffer fills. To avoid that, stdout
and stderr
should be read simultaneously (using threads or IO.select
).
Related:
Open3.popen2
: Makes the standard input and standard output streams of the child process available as separate streams, with no access to the standard error stream.
Open3.popen2e
: Makes the standard input and the merge of the standard output and standard error streams of the child process available as separate streams.
def capture2(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2(*cmd, opts) {|i, o, t| if binmode i.binmode o.binmode end out_reader = Thread.new { o.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [out_reader.value, t.value] } end
Basically a wrapper for Open3.popen3
that:
Creates a child process, by calling Open3.popen3
with the given arguments (except for certain entries in hash options
; see below).
Returns as string stdout_s
the standard output of the child process.
Returns as status
a Process::Status
object that represents the exit status of the child process.
Returns the array [stdout_s, status]
:
stdout_s, status = Open3.capture2('echo "Foo"')
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Open3.popen3
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Open3.popen3
; see Execution Options.
The hash options
is given; two options have local effect in method Open3.capture2
:
If entry options[:stdin_data]
exists, the entry is removed and its string value is sent to the commandâs standard input:
Open3.capture2('tee', stdin_data: 'Foo')
If entry options[:binmode]
exists, the entry is removed and the internal streams are set to binary mode.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.capture2('if true; then echo "Foo"; fi') Open3.capture2('echo') Open3.capture2('date > date.tmp')
The command line may also contain arguments and options for the command:
Open3.capture2('echo "Foo"')
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.capture2('/usr/bin/date')
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture2('doesnt_exist')
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.capture2('echo', 'C #') Open3.capture2('echo', 'hello', 'world')Source
def capture2e(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2e(*cmd, opts) {|i, oe, t| if binmode i.binmode oe.binmode end outerr_reader = Thread.new { oe.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [outerr_reader.value, t.value] } end
Basically a wrapper for Open3.popen3
that:
Creates a child process, by calling Open3.popen3
with the given arguments (except for certain entries in hash options
; see below).
Returns as string stdout_and_stderr_s
the merged standard output and standard error of the child process.
Returns as status
a Process::Status
object that represents the exit status of the child process.
Returns the array [stdout_and_stderr_s, status]
:
stdout_and_stderr_s, status = Open3.capture2e('echo "Foo"')
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Open3.popen3
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Open3.popen3
; see Execution Options.
The hash options
is given; two options have local effect in method Open3.capture2e
:
If entry options[:stdin_data]
exists, the entry is removed and its string value is sent to the commandâs standard input:
Open3.capture2e('tee', stdin_data: 'Foo')
If entry options[:binmode]
exists, the entry is removed and the internal streams are set to binary mode.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.capture2e('if true; then echo "Foo"; fi') Open3.capture2e('echo') Open3.capture2e('date > date.tmp')
The command line may also contain arguments and options for the command:
Open3.capture2e('echo "Foo"')
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.capture2e('/usr/bin/date')
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture2e('doesnt_exist')
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.capture2e('echo', 'C #') Open3.capture2e('echo', 'hello', 'world')Source
def capture3(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) || '' binmode = opts.delete(:binmode) popen3(*cmd, opts) {|i, o, e, t| if binmode i.binmode o.binmode e.binmode end out_reader = Thread.new { o.read } err_reader = Thread.new { e.read } begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end i.close [out_reader.value, err_reader.value, t.value] } end
Basically a wrapper for Open3.popen3
that:
Creates a child process, by calling Open3.popen3
with the given arguments (except for certain entries in hash options
; see below).
Returns as strings stdout_s
and stderr_s
the standard output and standard error of the child process.
Returns as status
a Process::Status
object that represents the exit status of the child process.
Returns the array [stdout_s, stderr_s, status]
:
stdout_s, stderr_s, status = Open3.capture3('echo "Foo"')
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Open3.popen3
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Open3.popen3
; see Execution Options.
The hash options
is given; two options have local effect in method Open3.capture3
:
If entry options[:stdin_data]
exists, the entry is removed and its string value is sent to the commandâs standard input:
Open3.capture3('tee', stdin_data: 'Foo')
If entry options[:binmode]
exists, the entry is removed and the internal streams are set to binary mode.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.capture3('if true; then echo "Foo"; fi') Open3.capture3('echo') Open3.capture3('date > date.tmp')
The command line may also contain arguments and options for the command:
Open3.capture3('echo "Foo"')
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.capture3('/usr/bin/date')
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture3('doesnt_exist')
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.capture3('echo', 'C #') Open3.capture3('echo', 'hello', 'world')Source
def pipeline(*cmds) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end pipeline_run(cmds, opts, [], []) {|ts| ts.map(&:value) } end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the last child, to the callerâs stdout
.
Waits for the child processes to exit.
Returns an array of Process::Status
objects (one for each child).
Example:
wait_threads = Open3.pipeline('ls', 'grep R')
Output:
Rakefile README.md
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
â see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_r(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [out_w], [out_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the last child, to the callerâs stdout
.
The method does not wait for child processes to exit, so the caller must do so.
With no block given, returns a 2-element array containing:
The stdout
stream of the last child process.
An array of the wait threads for all of the child processes.
Example:
last_stdout, wait_threads = Open3.pipeline_r('ls', 'grep R') puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
Output:
Rakefile README.md
With a block given, calls the block with the stdout
stream of the last child process, and an array of the wait processes:
Open3.pipeline_r('ls', 'grep R') do |last_stdout, wait_threads| puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
Output:
Rakefile README.md
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_rw(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the first child, from the callerâs stdin
, or, for the last child, to the callerâs stdout
.
The method does not wait for child processes to exit, so the caller must do so.
With no block given, returns a 3-element array containing:
The stdin
stream of the first child process.
The stdout
stream of the last child process.
An array of the wait threads for all of the child processes.
Example:
first_stdin, last_stdout, wait_threads = Open3.pipeline_rw('sort', 'cat -n') first_stdin.puts("foo\nbar\nbaz") first_stdin.close puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
Output:
1 bar 2 baz 3 foo
With a block given, calls the block with the stdin
stream of the first child, the stdout
stream of the last child, and an array of the wait processes:
Open3.pipeline_rw('sort', 'cat -n') do |first_stdin, last_stdout, wait_threads| first_stdin.puts "foo\nbar\nbaz" first_stdin.close puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
Output:
1 bar 2 baz 3 foo
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_start(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end if block pipeline_run(cmds, opts, [], [], &block) else ts, = pipeline_run(cmds, opts, [], []) ts end end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Does not wait for child processes to exit.
With no block given, returns an array of the wait threads for all of the child processes.
Example:
wait_threads = Open3.pipeline_start('ls', 'grep R') wait_threads.each do |wait_thread| wait_thread.join end
Output:
Rakefile README.md
With a block given, calls the block with an array of the wait processes:
Open3.pipeline_start('ls', 'grep R') do |wait_threads| wait_threads.each do |wait_thread| wait_thread.join end end
Output:
Rakefile README.md
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef pipeline_w(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true pipeline_run(cmds, opts, [in_r], [in_w], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process for each of the given cmds
by calling Process.spawn
.
Pipes the stdout
from each child to the stdin
of the next child, or, for the first child, pipes the callerâs stdout
to the childâs stdin
.
The method does not wait for child processes to exit, so the caller must do so.
With no block given, returns a 2-element array containing:
The stdin
stream of the first child process.
An array of the wait threads for all of the child processes.
Example:
first_stdin, wait_threads = Open3.pipeline_w('sort', 'cat -n') first_stdin.puts("foo\nbar\nbaz") first_stdin.close wait_threads.each do |wait_thread| wait_thread.join end
Output:
1 bar 2 baz 3 foo
With a block given, calls the block with the stdin
stream of the first child process, and an array of the wait processes:
Open3.pipeline_w('sort', 'cat -n') do |first_stdin, wait_threads| first_stdin.puts("foo\nbar\nbaz") first_stdin.close wait_threads.each do |wait_thread| wait_thread.join end end
Output:
1 bar 2 baz 3 foo
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If the first argument is a hash, it becomes leading argument env
in each call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in each call to Process.spawn
; see Execution Options.
Each remaining argument in cmds
is one of:
A command_line
: a string that begins with a shell reserved word or special built-in, or contains one or more metacharacters.
An exe_path
: the string path to an executable to be called.
An array containing a command_line
or an exe_path
, along with zero or more string arguments for the command.
See Argument command_line or exe_path.
Sourcedef popen2(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process, by calling Process.spawn
with the given arguments.
Creates streams stdin
and stdout
, which are the standard input and standard output streams in the child process.
Creates thread wait_thread
that waits for the child process to exit; the thread has method pid
, which returns the process ID of the child process.
With no block given, returns the array [stdin, stdout, wait_thread]
. The caller should close each of the two returned streams.
stdin, stdout, wait_thread = Open3.popen2('echo') stdin.close stdout.close wait_thread.pid wait_thread.value
With a block given, calls the block with the three variables (two streams and the wait thread) and returns the blockâs return value. The caller need not close the streams:
Open3.popen2('echo') do |stdin, stdout, wait_thread| p stdin p stdout p wait_thread p wait_thread.pid p wait_thread.value end
Output:
2263636
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Process.spawn
; see Execution Options.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.popen2('if true; then echo "Foo"; fi') {|*args| p args } Open3.popen2('echo') {|*args| p args } Open3.popen2('date > date.tmp') {|*args| p args }
Output (similar for each call above):
The command line may also contain arguments and options for the command:
Open3.popen2('echo "Foo"') { |i, o, t| o.gets } "Foo\n"
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.popen2('/usr/bin/date') { |i, o, t| o.gets }
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen2('doesnt_exist') { |i, o, t| o.gets }
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.popen2('echo', 'C #') { |i, o, t| o.gets } Open3.popen2('echo', 'hello', 'world') { |i, o, t| o.gets }
Related:
Open3.popen2e
: Makes the standard input and the merge of the standard output and standard error streams of the child process available as separate streams.
Open3.popen3
: Makes the standard input, standard output, and standard error streams of the child process available as separate streams.
def popen2e(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[[:out, :err]] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) ensure if block in_r.close in_w.close out_r.close out_w.close end end
Basically a wrapper for Process.spawn
that:
Creates a child process, by calling Process.spawn
with the given arguments.
Creates streams stdin
, stdout_and_stderr
, which are the standard input and the merge of the standard output and standard error streams in the child process.
Creates thread wait_thread
that waits for the child process to exit; the thread has method pid
, which returns the process ID of the child process.
With no block given, returns the array [stdin, stdout_and_stderr, wait_thread]
. The caller should close each of the two returned streams.
stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo') stdin.close stdout_and_stderr.close wait_thread.pid wait_thread.value
With a block given, calls the block with the three variables (two streams and the wait thread) and returns the blockâs return value. The caller need not close the streams:
Open3.popen2e('echo') do |stdin, stdout_and_stderr, wait_thread| p stdin p stdout_and_stderr p wait_thread p wait_thread.pid p wait_thread.value end
Output:
2274763
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Process.spawn
; see Execution Options.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.popen2e('if true; then echo "Foo"; fi') {|*args| p args } Open3.popen2e('echo') {|*args| p args } Open3.popen2e('date > date.tmp') {|*args| p args }
Output (similar for each call above):
The command line may also contain arguments and options for the command:
Open3.popen2e('echo "Foo"') { |i, o_and_e, t| o_and_e.gets } "Foo\n"
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.popen2e('/usr/bin/date') { |i, o_and_e, t| o_and_e.gets }
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen2e('doesnt_exist') { |i, o_and_e, t| o_and_e.gets }
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.popen2e('echo', 'C #') { |i, o_and_e, t| o_and_e.gets } Open3.popen2e('echo', 'hello', 'world') { |i, o_and_e, t| o_and_e.gets }
Related:
Open3.popen2
: Makes the standard input and standard output streams of the child process available as separate streams, with no access to the standard error stream.
Open3.popen3
: Makes the standard input, standard output, and standard error streams of the child process available as separate streams.
def popen3(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w err_r, err_w = IO.pipe opts[:err] = err_w popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) end
Basically a wrapper for Process.spawn
that:
Creates a child process, by calling Process.spawn
with the given arguments.
Creates streams stdin
, stdout
, and stderr
, which are the standard input, standard output, and standard error streams in the child process.
Creates thread wait_thread
that waits for the child process to exit; the thread has method pid
, which returns the process ID of the child process.
With no block given, returns the array [stdin, stdout, stderr, wait_thread]
. The caller should close each of the three returned streams.
stdin, stdout, stderr, wait_thread = Open3.popen3('echo') stdin.close stdout.close stderr.close wait_thread.pid wait_thread.value
With a block given, calls the block with the four variables (three streams and the wait thread) and returns the blockâs return value. The caller need not close the streams:
Open3.popen3('echo') do |stdin, stdout, stderr, wait_thread| p stdin p stdout p stderr p wait_thread p wait_thread.pid p wait_thread.value end
Output:
2211047
Like Process.spawn
, this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
Unlike Process.spawn
, this method waits for the child process to exit before returning, so the caller need not do so.
If the first argument is a hash, it becomes leading argument env
in the call to Process.spawn
; see Execution Environment.
If the last argument is a hash, it becomes trailing argument options
in the call to Process.spawn
; see Execution Options.
The single required argument is one of the following:
command_line
if it is a string, and if it begins with a shell reserved word or special built-in, or if it contains one or more metacharacters.
exe_path
otherwise.
Argument command_line
String argument command_line
is a command line to be passed to a shell; it must begin with a shell reserved word, begin with a special built-in, or contain meta characters:
Open3.popen3('if true; then echo "Foo"; fi') {|*args| p args } Open3.popen3('echo') {|*args| p args } Open3.popen3('date > date.tmp') {|*args| p args }
Output (similar for each call above):
[#<IO:(closed)>, #<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f58d52f28c8 dead>]
The command line may also contain arguments and options for the command:
Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets } "Foo\n"
Argument exe_path
Argument exe_path
is one of the following:
The string path to an executable to be called.
A 2-element array containing the path to an executable and the string to be used as the name of the executing process.
Example:
Open3.popen3('/usr/bin/date') { |i, o, e, t| o.gets }
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets }
If one or more args
is given, each is an argument or option to be passed to the executable:
Open3.popen3('echo', 'C #') { |i, o, e, t| o.gets } Open3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets }
Take care to avoid deadlocks. Output streams stdout
and stderr
have fixed-size buffers, so reading extensively from one but not the other can cause a deadlock when the unread buffer fills. To avoid that, stdout
and stderr
should be read simultaneously (using threads or IO.select
).
Related:
Open3.popen2
: Makes the standard input and standard output streams of the child process available as separate streams, with no access to the standard error stream.
Open3.popen2e
: Makes the standard input and the merge of the standard output and standard error streams of the child process available as separate streams.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3