IO#popen and exit status

I’m a bit stuck with this porblem:
I need to write data to a process and then wait for the exit code of it
to
see if it was successful or not.

Now I can IO.popen the process but there is no pclose instance method to
get the exitcode back. Additionally my workaround via Process.waitpid2
does
not work either. I think io.close does already all the cleanup.

e.g.

io = IO.popen(cmd, “w”)
io.write(msg)
io.close
pid, status = Process.waitpid2(0)

Raises a “Errno::ECHILD: No child processes” exception.

How do other handle this situation? Do I need to take the hard road via
pipe, fork, exec or did I miss something obvious?

On Tue, 21 Mar 2006 01:20:36 +0900, Claudio J.
[email protected] wrote:

[snip]

Now I can IO.popen the process but there is no pclose instance method to
get the exitcode back. Additionally my workaround via Process.waitpid2 does
not work either. I think io.close does already all the cleanup.

The $? variable will hold the exit status of the last child to
terminate.

andrew

On Tue, 21 Mar 2006, Claudio J. wrote:

io = IO.popen(cmd, “w”)
io.write(msg)
io.close
pid, status = Process.waitpid2(0)

Raises a “Errno::ECHILD: No child processes” exception.

How do other handle this situation? Do I need to take the hard road via
pipe, fork, exec or did I miss something obvious?

gem install open4

-a

Andrew J. wrote:

andrew

$? does not work with popen, or open3. I am not sure why one would want
to run a process, and monitor the output, yet not care what the exit
status is? One would think that this oversite will be fixed in future
releases.

~S

Actually I just solved this a few threads below. You can just run
Process.wait after you’ve done with the IO.popen and it should update
$? with the correct values.

Shea M. wrote:

The $? variable will hold the exit status of the last child to terminate.

andrew

$? does not work with popen, or open3. I am not sure why one would want
to run a process, and monitor the output, yet not care what the exit
status is? One would think that this oversite will be fixed in future
releases.

~S
ps - you can call Process.wait to update $?, but it is not reliable if
your program is multi threaded.

$? does not work with popen, or open3. I am not sure why one would want
to run a process, and monitor the output, yet not care what the exit
status is? One would think that this oversite will be fixed in future
releases.

~S

Before I get flamed, know Process.waitpid can be used…
~S

In article [email protected],
Claudio J. [email protected] writes:

I’m a bit stuck with this porblem:
I need to write data to a process and then wait for the exit code of it to
see if it was successful or not.

Now I can IO.popen the process but there is no pclose instance method to
get the exitcode back. Additionally my workaround via Process.waitpid2 does
not work either. I think io.close does already all the cleanup.

$? can be used after close.

I hope this documentation helps.

Index: io.c

RCS file: /src/ruby/io.c,v
retrieving revision 1.246.2.97
diff -u -p -r1.246.2.97 io.c
— io.c 14 Feb 2006 02:23:33 -0000 1.246.2.97
+++ io.c 28 Mar 2006 01:47:15 -0000
@@ -2149,6 +2149,9 @@ rb_io_close(io)

  • an IOError is raised if such an attempt is made. I/O
  • streams are automatically closed when they are claimed by the
  • garbage collector.
    • If ios is opened by IO.popen,
    • close sets $?.
      */

static VALUE
@@ -3062,7 +3065,9 @@ retry:
*

  • 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. In this case IO::popen returns
    • 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 ``-’’,
      @@ -3078,6 +3083,7 @@ retry:
    • 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:

@@ -3086,6 +3092,7 @@ retry:

  • 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

a = IO.popen(process)
a.close
and $? will be set immediately after the call to close succeeds.

Alternatively, if a block is given, at the end of block, Ruby closes the
pipe and sets $?.

See http://www.rubydoc.info/stdlib/core/IO.popen

“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.”

not work either. I think io.close does already all the cleanup.

$? can be used after close.

I hope this documentation helps.

Just so there is no confusion for others that run into this since google
brought me straight here, you can do:

a = IO.popen(process)
a.close
and $? will be set immediately after the call to close succeeds.

Process.waitpid is not necessary.

Nice chain of topic resurrection…

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs