module Open3
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_lineorexe_path; see Argument command_line or exe_path. -
An optional hash of execution options; see Execution Options.
Public Class Methods
(*String, ?stdin_data: String, ?binmode: boolish) → [ String, Process::Status ]
(env, *String, ?stdin_data: String, ?binmode: boolish) → [ String, Process::Status ]
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/stdlib/open3/0/open3.rbs, line 148
def self?.capture2: (*String, ?stdin_data: String, ?binmode: boolish) -> [String, Process::Status]
| (env, *String, ?stdin_data: String, ?binmode: boolish) -> [String, Process::Status]
Basically a wrapper for Open3.popen3 that:
-
Creates a child process, by calling
Open3.popen3with the given arguments (except for certain entries in hashoptions; see below). -
Returns as string
stdout_sthe standard output of the child process. -
Returns as
statusaProcess::Statusobject that represents the exit status of the child process.
Returns the array [stdout_s, status]:
stdout_s, status = Open3.capture2('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326047 exit 0>]
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') # => ["Foo", #<Process::Status: pid 2326087 exit 0>]
-
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_lineif 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_pathotherwise.
<strong>Argument command_line</strong>
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') # Shell reserved word. # => ["Foo\n", #<Process::Status: pid 2326131 exit 0>] Open3.capture2('echo') # Built-in. # => ["\n", #<Process::Status: pid 2326139 exit 0>] Open3.capture2('date > date.tmp') # Contains meta character. # => ["", #<Process::Status: pid 2326174 exit 0>]
The command line may also contain arguments and options for the command:
Open3.capture2('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
<strong>Argument exe_path</strong>
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') # => ["Fri Sep 29 01:00:39 PM CDT 2023\n", #<Process::Status: pid 2326222 exit 0>]
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture2('doesnt_exist') # Raises Errno::ENOENT
If one or more args is given, each is an argument or option to be passed to the executable:
Open3.capture2('echo', 'C #') # => ["C #\n", #<Process::Status: pid 2326267 exit 0>] Open3.capture2('echo', 'hello', 'world') # => ["hello world\n", #<Process::Status: pid 2326299 exit 0>]
(*String, ?stdin_data: String, ?binmode: boolish) → [ String, Process::Status ]
(env, *String, ?stdin_data: String, ?binmode: boolish) → [ String, Process::Status ]
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/stdlib/open3/0/open3.rbs, line 246
def self?.capture2e: (*String, ?stdin_data: String, ?binmode: boolish) -> [String, Process::Status]
| (env, *String, ?stdin_data: String, ?binmode: boolish) -> [String, Process::Status]
Basically a wrapper for Open3.popen3 that:
-
Creates a child process, by calling
Open3.popen3with the given arguments (except for certain entries in hashoptions; see below). -
Returns as string
stdout_and_stderr_sthe merged standard output and standard error of the child process. -
Returns as
statusaProcess::Statusobject 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"') # => ["Foo\n", #<Process::Status: pid 2371692 exit 0>]
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') # => ["Foo", #<Process::Status: pid 2371732 exit 0>]
-
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_lineif 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_pathotherwise.
<strong>Argument command_line</strong>
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') # Shell reserved word. # => ["Foo\n", #<Process::Status: pid 2371740 exit 0>] Open3.capture2e('echo') # Built-in. # => ["\n", #<Process::Status: pid 2371774 exit 0>] Open3.capture2e('date > date.tmp') # Contains meta character. # => ["", #<Process::Status: pid 2371812 exit 0>]
The command line may also contain arguments and options for the command:
Open3.capture2e('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
<strong>Argument exe_path</strong>
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') # => ["Sat Sep 30 09:01:46 AM CDT 2023\n", #<Process::Status: pid 2371820 exit 0>]
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture2e('doesnt_exist') # Raises Errno::ENOENT
If one or more args is given, each is an argument or option to be passed to the executable:
Open3.capture2e('echo', 'C #') # => ["C #\n", #<Process::Status: pid 2371856 exit 0>] Open3.capture2e('echo', 'hello', 'world') # => ["hello world\n", #<Process::Status: pid 2371894 exit 0>]
(*String, ?stdin_data: String, ?binmode: boolish) → [ String, String, Process::Status ]
(env, *String, ?stdin_data: String, ?binmode: boolish) → [ String, String, Process::Status ]
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/stdlib/open3/0/open3.rbs, line 344
def self?.capture3: (*String, ?stdin_data: String, ?binmode: boolish) -> [String, String, Process::Status]
| (env, *String, ?stdin_data: String, ?binmode: boolish) -> [String, String, Process::Status]
Basically a wrapper for Open3.popen3 that:
-
Creates a child process, by calling
Open3.popen3with the given arguments (except for certain entries in hashoptions; see below). -
Returns as strings
stdout_sandstderr_sthe standard output and standard error of the child process. -
Returns as
statusaProcess::Statusobject 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"') # => ["Foo\n", "", #<Process::Status: pid 2281954 exit 0>]
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') # => ["Foo", "", #<Process::Status: pid 2319575 exit 0>]
-
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_lineif 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_pathotherwise.
<strong>Argument command_line</strong>
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') # Shell reserved word. # => ["Foo\n", "", #<Process::Status: pid 2282025 exit 0>] Open3.capture3('echo') # Built-in. # => ["\n", "", #<Process::Status: pid 2282092 exit 0>] Open3.capture3('date > date.tmp') # Contains meta character. # => ["", "", #<Process::Status: pid 2282110 exit 0>]
The command line may also contain arguments and options for the command:
Open3.capture3('echo "Foo"') # => ["Foo\n", "", #<Process::Status: pid 2282092 exit 0>]
<strong>Argument exe_path</strong>
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') # => ["Thu Sep 28 05:03:51 PM CDT 2023\n", "", #<Process::Status: pid 2282300 exit 0>]
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.capture3('doesnt_exist') # Raises Errno::ENOENT
If one or more args is given, each is an argument or option to be passed to the executable:
Open3.capture3('echo', 'C #') # => ["C #\n", "", #<Process::Status: pid 2282368 exit 0>] Open3.capture3('echo', 'hello', 'world') # => ["hello world\n", "", #<Process::Status: pid 2282372 exit 0>]
(*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) → [ IO, IO, Process::Waiter ]
(env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) → [ IO, IO, Process::Waiter ]
[T] (*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, Process::Waiter) → T } → T
[T] (env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, Process::Waiter) → T } → T
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/stdlib/open3/0/open3.rbs, line 467
def self?.popen2: (*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) -> [IO, IO, Process::Waiter]
| (env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) -> [IO, IO, Process::Waiter]
| [T] (*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, Process::Waiter) -> T } -> T
| [T] (env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, Process::Waiter) -> T } -> T
Basically a wrapper for Process.spawn that:
-
Creates a child process, by calling Process.spawn with the given arguments.
-
Creates streams
stdinandstdout, which are the standard input and standard output streams in the child process. -
Creates thread
wait_threadthat waits for the child process to exit; the thread has methodpid, 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') # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f58d52dbe98 run>] stdin.close stdout.close wait_thread.pid # => 2263572 wait_thread.value # => #<Process::Status: pid 2263572 exit 0>
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:
#<IO:fd 6> #<IO:fd 7> #<Process::Waiter:0x00007f58d59a34b0 sleep> 2263636 #<Process::Status: pid 2263636 exit 0>
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_lineif 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_pathotherwise.
<strong>Argument command_line</strong>
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 } # Shell reserved word. Open3.popen2('echo') {|*args| p args } # Built-in. Open3.popen2('date > date.tmp') {|*args| p args } # Contains meta character.
Output (similar for each call above):
# => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577dfe410 dead>]
The command line may also contain arguments and options for the command:
Open3.popen2('echo "Foo"') { |i, o, t| o.gets } "Foo\n"
<strong>Argument exe_path</strong>
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 } # => "Thu Sep 28 09:41:06 AM CDT 2023\n"
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen2('doesnt_exist') { |i, o, t| o.gets } # Raises Errno::ENOENT
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 } # => "C #\n" Open3.popen2('echo', 'hello', 'world') { |i, o, t| o.gets } # => "hello world\n"
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.
(*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) → [ IO, IO, IO, Process::Waiter ]
(env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) → [ IO, IO, IO, Process::Waiter ]
[T] (*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, IO, Process::Waiter) → T } → T
[T] (env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, IO, Process::Waiter) → T } → T
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/stdlib/open3/0/open3.rbs, line 602
def self?.popen3: (*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) -> [IO, IO, IO, Process::Waiter]
| (env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) -> [IO, IO, IO, Process::Waiter]
| [T] (*String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, IO, Process::Waiter) -> T } -> T
| [T] (env, *String, ?unsetenv_others: bool, ?pgroup: true | Integer, ?umask: Integer, ?close_others: bool, ?chdir: String) { (IO, IO, IO, Process::Waiter) -> T } -> T
Basically a wrapper for Process.spawn that:
-
Creates a child process, by calling Process.spawn with the given arguments.
-
Creates streams
stdin,stdout, andstderr, which are the standard input, standard output, and standard error streams in the child process. -
Creates thread
wait_threadthat waits for the child process to exit; the thread has methodpid, 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') # => [#<IO:fd 8>, #<IO:fd 10>, #<IO:fd 12>, #<Process::Waiter:0x00007f58d5428f58 run>] stdin.close stdout.close stderr.close wait_thread.pid # => 2210481 wait_thread.value # => #<Process::Status: pid 2210481 exit 0>
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:
#<IO:fd 6> #<IO:fd 7> #<IO:fd 9> #<Process::Waiter:0x00007f58d53606e8 sleep> 2211047 #<Process::Status: pid 2211047 exit 0>
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_lineif 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_pathotherwise.
<strong>Argument command_line</strong>
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 } # Shell reserved word. Open3.popen3('echo') {|*args| p args } # Built-in. Open3.popen3('date > date.tmp') {|*args| p args } # Contains meta character.
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"
<strong>Argument exe_path</strong>
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 } # => "Wed Sep 27 02:56:44 PM CDT 2023\n"
Ruby invokes the executable directly, with no shell and no shell expansion:
Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets } # Raises Errno::ENOENT
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 } # => "C #\n" Open3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets } # => "hello world\n"
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.