Method: IO.popen
- Defined in:
- io.c
.popen([env,], mode = "r"[, opt]) ⇒ IO .popen([env,], mode = "r"[, opt]) {|io| ... } ⇒ Object
Runs the specified command as a subprocess; the subprocess’s standard input and output will be connected to the returned IO object.
The PID of the started process can be obtained by IO#pid method.
cmd is a string or an array as follows.
cmd:
"-" : fork
commandline : command line string which is passed to a shell
[env, cmdname, arg1, ..., opts] : command name and zero or more arguments (no shell)
[env, [cmdname, argv0], arg1, ..., opts] : command name, argv[0] and zero or more arguments (no shell)
(env and opts are optional.)
If cmd is a String
“-
”, then a new instance of Ruby is started as the subprocess.
If cmd is an Array
of String
, then it will be used as the subprocess’s argv
bypassing a shell. The array can contain a hash at first for environments and a hash at last for options similar to #spawn.
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. The last argument opt qualifies mode.
# set IO encoding
IO.popen("nkf -e filename", :external_encoding=>"EUC-JP") {|nkf_io|
euc_jp_string = nkf_io.read
}
# merge standard output and standard error using
# spawn option. See the document of Kernel.spawn.
IO.popen(["ls", "/", :err=>[:child, :out]]) {|ls_io|
ls_result_with_error = ls_io.read
}
# spawn options can be mixed with IO options
IO.popen(["ls", "/"], :err=>[:child, :out]) {|ls_io|
ls_result_with_error = ls_io.read
}
Raises exceptions which IO.pipe and Kernel.spawn raise.
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 closes the pipe and sets $?
. In this case IO.popen returns the value of the block.
If a block is given with a cmd 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
f.close
puts "Parent is #{Process.pid}"
IO.popen("date") {|f| puts f.gets }
IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f.inspect}"}
p $?
IO.popen(%w"sed -e s|^|<foo>| -e s&$&;zot;&", "r+") {|f|
f.puts "bar"; f.close_write; puts f.gets
}
produces:
["Linux\n"]
Parent is 21346
Thu Jan 15 22:41:19 JST 2009
21346 is here, f is #<IO:fd 3>
21352 is here, f is nil
#<Process::Status: pid 21352 exit 0>
<foo>bar;zot;
7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 |
# File 'io.c', line 7011
static VALUE
rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
{
VALUE pname, pmode = Qnil, opt = Qnil, env = Qnil;
if (argc > 1 && !NIL_P(opt = rb_check_hash_type(argv[argc-1]))) --argc;
if (argc > 1 && !NIL_P(env = rb_check_hash_type(argv[0]))) --argc, ++argv;
switch (argc) {
case 2:
pmode = argv[1];
case 1:
pname = argv[0];
break;
default:
{
int ex = !NIL_P(opt);
rb_error_arity(argc + ex, 1 + ex, 2 + ex);
}
}
return popen_finish(rb_io_popen(pname, pmode, env, opt), klass);
}
|