End of Life Ruby 3.2 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
Kernel#open
static VALUE
rb_f_open(int argc, VALUE *argv, VALUE _)
{
ID to_open = 0;
int redirect = FALSE;
if (argc >= 1) {
CONST_ID(to_open, "to_open");
if (rb_respond_to(argv[0], to_open)) {
redirect = TRUE;
}
else {
VALUE tmp = argv[0];
FilePathValue(tmp);
if (NIL_P(tmp)) {
redirect = TRUE;
}
else {
VALUE cmd = check_pipe_command(tmp);
if (!NIL_P(cmd)) {
argv[0] = cmd;
return rb_io_s_popen(argc, argv, rb_cIO);
}
}
}
}
if (redirect) {
VALUE io = rb_funcallv_kw(argv[0], to_open, argc-1, argv+1, RB_PASS_CALLED_KEYWORDS);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
}
return io;
}
return rb_io_s_open(argc, argv, rb_cFile);
}
Creates an IO object connected to the given stream, file, or subprocess.
Required string argument path determines which of the following occurs:
-
The file at the specified
pathis opened. -
The process forks.
-
A subprocess is created.
Each of these is detailed below.
File Opened
If path does not start with a pipe character ('|'), a file stream is opened with File.open(path, mode, perm, **opts).
With no block given, file stream is returned:
open('t.txt') # => #<File:t.txt>
With a block given, calls the block with the open file stream, then closes the stream:
open('t.txt') {|f| p f } # => #<File:t.txt (closed)>
Output:
#<File:t.txt>
See File.open for details.
Process Forked
If path is the 2-character string '|-', the process forks and the child process is connected to the parent.
With no block given:
io = open('|-') if io $stderr.puts "In parent, child pid is #{io.pid}." else $stderr.puts "In child, pid is #{$$}." end
Output:
In parent, child pid is 27903. In child, pid is 27903.
With a block given:
open('|-') do |io| if io $stderr.puts "In parent, child pid is #{io.pid}." else $stderr.puts "In child, pid is #{$$}." end end
Output:
In parent, child pid is 28427. In child, pid is 28427.
Subprocess Created
If path is '|command' ('command' != '-'), a new subprocess runs the command; its open stream is returned. Note that the command may be processed by shell if it contains shell metacharacters.
With no block given:
io = open('|echo "Hi!"') # => #<IO:fd 12> print io.gets io.close
Output:
"Hi!"
With a block given, calls the block with the stream, then closes the stream:
open('|echo "Hi!"') do |io| print io.gets end
Output:
"Hi!"