Jump to page: 1 2
Thread overview
How would I retrieve the stdout error message of a system/shell command?
Sep 08, 2011
Andrej Mitrovic
Sep 08, 2011
Justin Whear
Sep 08, 2011
Timon Gehr
Sep 08, 2011
Justin Whear
Sep 08, 2011
Christophe
Sep 08, 2011
Justin Whear
Sep 08, 2011
Timon Gehr
Sep 08, 2011
Justin Whear
Sep 08, 2011
Andrej Mitrovic
Sep 09, 2011
Regan Heath
September 08, 2011
E.g.:

import std.process;

void main()
{
    auto res = shell("dmd bla.d");
}

where bla.d doesn't exist. This will throw an exception, but even if I caught the exception I will still loose the error message. Is there any way I could grab the error message? In this case it would be:

"std.exception.ErrnoException@std\process.d(356):  (No error)"

Okay that's a pretty useless error as it is, but other errors might be more informative and I'd like to grab them.
September 08, 2011
The Posix solution is to use pipes. Basically, you'll want the parent
process to set up a pipe for stderr, fork, then the child process uses the
write end of the stderr while the parent reads from the other end. Not sure
what the Windoze solution is.
Alternatively, the cheap and easy way is to use redirects:

system("dmd bla.d 2>error.log");

If an error is thrown, read from error.log.
September 08, 2011
On 09/08/2011 07:26 PM, Justin Whear wrote:
> The Posix solution is to use pipes. Basically, you'll want the parent
> process to set up a pipe for stderr, fork, then the child process uses the
> write end of the stderr while the parent reads from the other end. Not sure
> what the Windoze solution is.
> Alternatively, the cheap and easy way is to use redirects:
>
> system("dmd bla.d 2>error.log");
>
> If an error is thrown, read from error.log.

I think the easiest way on a posix system is this:

auto res=shell("dmd bla.d 2>&1");

I haven't tested it tough. What it should do is redirect dmd's stderr to stdout, which can then be read.
September 08, 2011
That'll work if you don't mind normal output being mixed with error messages.


Timon Gehr wrote:

> On 09/08/2011 07:26 PM, Justin Whear wrote:
>> The Posix solution is to use pipes. Basically, you'll want the parent
>> process to set up a pipe for stderr, fork, then the child process uses
>> the write end of the stderr while the parent reads from the other end.
>> Not sure what the Windoze solution is.
>> Alternatively, the cheap and easy way is to use redirects:
>>
>> system("dmd bla.d 2>error.log");
>>
>> If an error is thrown, read from error.log.
> 
> I think the easiest way on a posix system is this:
> 
> auto res=shell("dmd bla.d 2>&1");
> 
> I haven't tested it tough. What it should do is redirect dmd's stderr to stdout, which can then be read.

September 08, 2011
For posterity's sake, the "correct" (and much more complicated way) is to use pipes and fork(). Here's a Posix-only implementation I wrote a while ago: http://pastebin.com/CBYw4fDU

No guarantees on the code, but it demonstrates how to set up the pipes, etc. The cool thing is that it supports full two-way communication--the parent process can write to the child's stdin and read from both stdout and stderr.

Cheers,
Justin

September 08, 2011
Justin Whear , dans le message (digitalmars.D.learn:29380), a écrit :
> That'll work if you don't mind normal output being mixed with error messages.
> 
> 
> Timon Gehr wrote:
> 
>> On 09/08/2011 07:26 PM, Justin Whear wrote:
>>> The Posix solution is to use pipes. Basically, you'll want the parent
>>> process to set up a pipe for stderr, fork, then the child process uses
>>> the write end of the stderr while the parent reads from the other end.
>>> Not sure what the Windoze solution is.
>>> Alternatively, the cheap and easy way is to use redirects:
>>>
>>> system("dmd bla.d 2>error.log");
>>>
>>> If an error is thrown, read from error.log.
>> 
>> I think the easiest way on a posix system is this:
>> 
>> auto res=shell("dmd bla.d 2>&1");
>> 
>> I haven't tested it tough. What it should do is redirect dmd's stderr to stdout, which can then be read.
> 

Well, if shell throws, it will not return, and the output will not be assigned to res.
September 08, 2011
On Thu, 08 Sep 2011 14:14:40 -0400, Justin Whear <justin@economicmodeling.com> wrote:

> For posterity's sake, the "correct" (and much more complicated way) is to
> use pipes and fork(). Here's a Posix-only implementation I wrote a while
> ago: http://pastebin.com/CBYw4fDU
>
> No guarantees on the code, but it demonstrates how to set up the pipes, etc.
> The cool thing is that it supports full two-way communication--the parent
> process can write to the child's stdin and read from both stdout and stderr.

This is the plan for the revamped version of std.process, which is held up waiting for DMC changes.

-Steve
September 08, 2011
Good point. It looks like shell throws if the return value is an error code (something other than 0 on Posix). It looks like dmd does return an error code on failed compilation, so redirecting to stdout won't work. Back to the pipes or file redirect then.


Christophe wrote:

> Justin Whear , dans le message (digitalmars.D.learn:29380), a écrit :
>> That'll work if you don't mind normal output being mixed with error messages.
>> 
>> 
>> Timon Gehr wrote:
>> 
>>> On 09/08/2011 07:26 PM, Justin Whear wrote:
>>>> The Posix solution is to use pipes. Basically, you'll want the parent
>>>> process to set up a pipe for stderr, fork, then the child process uses
>>>> the write end of the stderr while the parent reads from the other end.
>>>> Not sure what the Windoze solution is.
>>>> Alternatively, the cheap and easy way is to use redirects:
>>>>
>>>> system("dmd bla.d 2>error.log");
>>>>
>>>> If an error is thrown, read from error.log.
>>> 
>>> I think the easiest way on a posix system is this:
>>> 
>>> auto res=shell("dmd bla.d 2>&1");
>>> 
>>> I haven't tested it tough. What it should do is redirect dmd's stderr to stdout, which can then be read.
>> 
> 
> Well, if shell throws, it will not return, and the output will not be assigned to res.

September 08, 2011
On 09/08/2011 08:21 PM, Justin Whear wrote:
> Good point. It looks like shell throws if the return value is an error code
> (something other than 0 on Posix). It looks like dmd does return an error
> code on failed compilation, so redirecting to stdout won't work. Back to the
> pipes or file redirect then.
>
>
> Christophe wrote:
>
>> Justin Whear , dans le message (digitalmars.D.learn:29380), a écrit :
>>> That'll work if you don't mind normal output being mixed with error
>>> messages.
>>>
>>>
>>> Timon Gehr wrote:
>>>
>>>> On 09/08/2011 07:26 PM, Justin Whear wrote:
>>>>> The Posix solution is to use pipes. Basically, you'll want the parent
>>>>> process to set up a pipe for stderr, fork, then the child process uses
>>>>> the write end of the stderr while the parent reads from the other end.
>>>>> Not sure what the Windoze solution is.
>>>>> Alternatively, the cheap and easy way is to use redirects:
>>>>>
>>>>> system("dmd bla.d 2>error.log");
>>>>>
>>>>> If an error is thrown, read from error.log.
>>>>
>>>> I think the easiest way on a posix system is this:
>>>>
>>>> auto res=shell("dmd bla.d 2>&1");
>>>>
>>>> I haven't tested it tough. What it should do is redirect dmd's stderr to
>>>> stdout, which can then be read.
>>>
>>
>> Well, if shell throws, it will not return, and the output will not be
>> assigned to res.
>

It seems DMD actually writes the error messages to stdout anyways.

This will stop shell from throwing:

auto res = shell("dmd bla.d | cat");



September 08, 2011
On 9/8/11, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> This is the plan for the revamped version of std.process, which is held up waiting for DMC changes.

That's good news, thanks. I'll try the various pipe/redirect methods soon.
« First   ‹ Prev
1 2