popen(...)
public
Runs the specified command string as a subprocess; the subprocess’s
standard input and output will be connected to the returned IO object. If cmd_string starts with a
“-”, then a new instance of Ruby is
started as the subprocess. The default mode for the new file object is “r”, but mode
may be set to any of the modes listed in the description for class IO.
If a block is given, Ruby will run the command as a child connected to Ruby
with a pipe. Ruby’s end of the pipe will be passed as a parameter to the
block. At the end of block, Ruby close the pipe and sets $?. In this case IO::popen
returns the value of the block.
If a block is given with a cmd_string of “-”, the block will
be run in two separate processes: once in the parent, and once in a child.
The parent process will be passed the pipe object as a parameter to the block, the
child version of the block will be passed nil, and the child’s standard
in and standard out will be connected to the parent through the pipe. Not available on all platforms.
f = IO.popen("uname")
p f.readlines
puts "Parent is #{Process.pid}"
IO.popen ("date") { |f| puts f.gets }
IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f}"}
p $?
produces:
["Linux\n"]
Parent is 26166
Wed Apr 9 08:53:52 CDT 2003
26169 is here, f is
26166 is here, f is
Show source
/*
* call-seq:
* IO.popen(cmd_string, mode="r" ) => io
* IO.popen(cmd_string, mode="r" ) {|io| block } => obj
*
* Runs the specified command string as a subprocess; the subprocess's
* standard input and output will be connected to the returned
* <code>IO</code> object. If <i>cmd_string</i> starts with a
* ``<code>-</code>'', then a new instance of Ruby is started as the
* subprocess. The default mode for the new file object is ``r'', but
* <i>mode</i> may be set to any of the modes listed in the description
* for class IO.
*
* If a block is given, Ruby will run the command as a child connected
* to Ruby with a pipe. Ruby's end of the pipe will be passed as a
* parameter to the block.
* At the end of block, Ruby close the pipe and sets <code>$?</code>.
* In this case <code>IO::popen</code> returns
* the value of the block.
*
* If a block is given with a <i>cmd_string</i> of ``<code>-</code>'',
* the block will be run in two separate processes: once in the parent,
* and once in a child. The parent process will be passed the pipe
* object as a parameter to the block, the child version of the block
* will be passed <code>nil</code>, and the child's standard in and
* standard out will be connected to the parent through the pipe. Not
* available on all platforms.
*
* f = IO.popen("uname")
* p f.readlines
* puts "Parent is #{Process.pid}"
* IO.popen ("date") { |f| puts f.gets }
* IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f}"}
* p $?
*
* <em>produces:</em>
*
* ["Linux\n"]
* Parent is 26166
* Wed Apr 9 08:53:52 CDT 2003
* 26169 is here, f is
* 26166 is here, f is #<IO:0x401b3d44>
* #<Process::Status: pid=26166,exited(0)>
*/
static VALUE
rb_io_s_popen(argc, argv, klass)
int argc;
VALUE *argv;
VALUE klass;
{
const char *mode;
VALUE pname, pmode, port;
if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) {
mode = "r";
}
else if (FIXNUM_P(pmode)) {
mode = rb_io_modenum_mode(FIX2INT(pmode));
}
else {
mode = rb_io_flags_mode(rb_io_mode_flags(StringValueCStr(pmode)));
}
SafeStringValue(pname);
port = pipe_open(pname, 0, mode);
if (NIL_P(port)) {
/* child */
if (rb_block_given_p()) {
rb_yield(Qnil);
fflush(stdout);
fflush(stderr);
_exit(0);
}
return Qnil;
}
RBASIC(port)->klass = klass;
if (rb_block_given_p()) {
return rb_ensure(rb_yield, port, io_close, port);
}
return port;
}