obtaining process exit code from popen()

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

obtaining process exit code from popen()

John D. Blair-2
Has anybody worked out how to obtain the exit code from a sub-process
invoked using popen()?

It looks to me that the exit code is currently discarded b/c the
standard __close meta-method only returns a boolean.

Would it be possible to define an alternate close method (i.e.,
pclose()) which one could use to close a stream opened using popen() and
obtain the exit code from the sub-process?  Has this already been done?

thanks much,
John.

Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

Asko Kauppi

I remember having done this years back, by appending "&& echo  
<returncode>" to the command itself (and being able to read the output).

<returncode> is whatever $ magic bash uses for showing the return code.

Had similar stuff also for Windows, I can dig up the archives if no-
one else gives a better solution.

It is a hack.

-asko

John D. Blair kirjoitti 6.6.2009 kello 3:20:

> Has anybody worked out how to obtain the exit code from a sub-process
> invoked using popen()?
>
> It looks to me that the exit code is currently discarded b/c the
> standard __close meta-method only returns a boolean.
>
> Would it be possible to define an alternate close method (i.e.,
> pclose()) which one could use to close a stream opened using popen()  
> and
> obtain the exit code from the sub-process?  Has this already been  
> done?
>
> thanks much,
> John.
>

Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

Patrick Donnelly
Hi Asko,

On Sat, Jun 6, 2009 at 1:50 AM, Asko Kauppi<[hidden email]> wrote:
>
> I remember having done this years back, by appending "&& echo <returncode>"
> to the command itself (and being able to read the output).

I believe you meant: "|| echo $?"

--
-Patrick Donnelly

"Let all men know thee, but no man know thee thoroughly: Men freely
ford that see the shallows."

- Benjamin Franklin
Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

steve donovan
On Sat, Jun 6, 2009 at 10:07 AM, Patrick Donnelly<[hidden email]> wrote:
> I believe you meant: "|| echo $?"

This is a fuller elaboration of the hack; you get the status code any
way (because you will need to strip it out with some pattern)

I checked out luaex, but ex.popen gives you a process-object and a
file handle. No way to tell from that, it appears.

steve d.

function command(cmd)
    local f = io.popen(cmd..'; echo "-retcode:$?"' ,'r')
    local l = f:read '*a'
    f:close()
    local i1,i2,ret = l:find('%-retcode:(%d+)\n$')
    l = l:sub(1,i1-1)
    return l,ret
end

print(command 'which lua')
Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

steve donovan
On Sat, Jun 6, 2009 at 11:54 AM, steve
donovan<[hidden email]> > This is a fuller elaboration of
the hack; you get the status code any
> way (because you will need to strip it out with some pattern)

Just for the record, this version covers most of the cases; it
redirects stderr, so that you can use to capture the full output of
'gcc' say.

function command(cmd,no_lf)
    local f = io.popen(cmd..' 2>&1; echo "-retcode:$?"' ,'r')
    local l = f:read '*a'
    f:close()
    local i1,i2,ret = l:find('%-retcode:(%d+)\n$')
    if no_lf and i1 > 1 then i1 = i1 - 1 end
    l = l:sub(1,i1-1)
    return l,tonumber(ret)
end

res,ret = command (arg[1],true)
print('result "'..res..'"')
print('retcode',ret)

Now the next question was whether it this can be done on Windows.
Not..quite. It has all the bits, you can do the '2>&1' trick (I didn't
know that!), the command separator is '&' not ';', and '%ERRORLEVEL%
does give the return code of the last command. Unfortunately, its
value is not updated immediately in compound commands! I will leave
this to the last surviving Windows power users ;)

It is a hack, true, but that's why it needs to be hidden in a library

steve d.
Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

Joshua Jensen
In reply to this post by steve donovan
----- Original Message -----
From: steve donovan
Date: 6/6/2009 3:54 AM
> I checked out luaex, but ex.popen gives you a process-object and a
> file handle. No way to tell from that, it appears.
>  
The process exit code is the return value from the process object's
wait() function:

exitcode = proc:wait()

Josh
Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

John D. Blair-2
On Sat, 2009-06-06 at 08:06 -0600, Joshua Jensen wrote:
> The process exit code is the return value from the process object's
> wait() function:
>
> exitcode = proc:wait()

I'm not sure I understand... popen() doesn't return a process object, it
returns a file handle.  Also, I don't see wait() or a process object in
the lua docs anyplace.  Is it part of an add-on module?  I don't think
there's any concept of process in ANSI-C, which is what the un-adorned
lua interpreter targets.

 -john.

Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

Florian Weimer
* John D. Blair:

> I'm not sure I understand... popen() doesn't return a process object, it
> returns a file handle.  Also, I don't see wait() or a process object in
> the lua docs anyplace.  Is it part of an add-on module?  I don't think
> there's any concept of process in ANSI-C, which is what the un-adorned
> lua interpreter targets.

popen() is from POSIX, not ISO C.  pclose() does return the exit
status of the child process.
Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

Joseph Stewart
In reply to this post by John D. Blair-2
I've hacked the use of pclose() in the standard libraries in the past
to obtain this value... my implementation is crude but I could share
the "recipe" with you if you're interested.

-joe

On Mon, Jun 8, 2009 at 3:40 PM, John D. Blair<[hidden email]> wrote:

> On Sat, 2009-06-06 at 08:06 -0600, Joshua Jensen wrote:
>> The process exit code is the return value from the process object's
>> wait() function:
>>
>> exitcode = proc:wait()
>
> I'm not sure I understand... popen() doesn't return a process object, it
> returns a file handle.  Also, I don't see wait() or a process object in
> the lua docs anyplace.  Is it part of an add-on module?  I don't think
> there's any concept of process in ANSI-C, which is what the un-adorned
> lua interpreter targets.
>
>  -john.
>
>
Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

John D. Blair-2
In reply to this post by Florian Weimer
On Mon, 2009-06-08 at 21:47 +0200, Florian Weimer wrote:

> * John D. Blair:
>
> > I'm not sure I understand... popen() doesn't return a process object, it
> > returns a file handle.  Also, I don't see wait() or a process object in
> > the lua docs anyplace.  Is it part of an add-on module?  I don't think
> > there's any concept of process in ANSI-C, which is what the un-adorned
> > lua interpreter targets.
>
> popen() is from POSIX, not ISO C.  pclose() does return the exit
> status of the child process.

That's not true about pclose(), at least not on Linux:

>From the Linux popen() man page, which also describes pclose():

       The pclose() function waits for the associated process to
terminate and returns the exit status of the command as returned by
wait4(2).



Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

John D. Blair-2
In reply to this post by Joseph Stewart
Its where I'm headed anyway, so I would appreciate seeing how you've
done it.

 -john.

On Mon, 2009-06-08 at 15:48 -0400, Joseph Stewart wrote:

> I've hacked the use of pclose() in the standard libraries in the past
> to obtain this value... my implementation is crude but I could share
> the "recipe" with you if you're interested.
>
> -joe
>
> On Mon, Jun 8, 2009 at 3:40 PM, John D. Blair<[hidden email]> wrote:
> > On Sat, 2009-06-06 at 08:06 -0600, Joshua Jensen wrote:
> >> The process exit code is the return value from the process object's
> >> wait() function:
> >>
> >> exitcode = proc:wait()
> >
> > I'm not sure I understand... popen() doesn't return a process object, it
> > returns a file handle.  Also, I don't see wait() or a process object in
> > the lua docs anyplace.  Is it part of an add-on module?  I don't think
> > there's any concept of process in ANSI-C, which is what the un-adorned
> > lua interpreter targets.
> >
> >  -john.
> >
> >

Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

Joshua Jensen
In reply to this post by John D. Blair-2
----- Original Message -----
From: John D. Blair
Date: 6/8/2009 1:40 PM
On Sat, 2009-06-06 at 08:06 -0600, Joshua Jensen wrote:
  
The process exit code is the return value from the process object's 
wait() function:

exitcode = proc:wait()
    
I'm not sure I understand... popen() doesn't return a process object, it
returns a file handle.  Also, I don't see wait() or a process object in
the lua docs anyplace.  Is it part of an add-on module?  I don't think
there's any concept of process in ANSI-C, which is what the un-adorned
lua interpreter targets.
  
I was responding to Steve Donovan's message about lua-ex.  See http://lua-users.org/lists/lua-l/2009-06/msg00135.html.

Josh
Reply | Threaded
Open this post in threaded view
|

Re: obtaining process exit code from popen()

John D. Blair-2
In reply to this post by John D. Blair-2
On Mon, 2009-06-08 at 22:37 +0200, Florian Weimer wrote:

> >> popen() is from POSIX, not ISO C.  pclose() does return the exit
> >> status of the child process.
> >
> > That's not true about pclose(), at least not on Linux:
> >
> >>From the Linux popen() man page, which also describes pclose():
> >
> >        The pclose() function waits for the associated process to
> > terminate and returns the exit status of the command as returned by
> > wait4(2).
>
> Which part is not true?  I'm confused.
>
> (Feel free to respond to the mailing list.)

Sorry... I misread your statement... I thought you wrote the opposite of
what you actually did.  I need to be more careful before I email.

best,
John.