digitalmars.D.learn - How would I retrieve the stdout error message of a system/shell
- Andrej Mitrovic (12/12) Sep 08 2011 E.g.:
- Justin Whear (7/7) Sep 08 2011 The Posix solution is to use pipes. Basically, you'll want the parent
- Timon Gehr (5/12) Sep 08 2011 I think the easiest way on a posix system is this:
- Justin Whear (3/20) Sep 08 2011 That'll work if you don't mind normal output being mixed with error
- travert phare.normalesup.org (Christophe) (3/27) Sep 08 2011 Well, if shell throws, it will not return, and the output will not be
- Justin Whear (5/33) Sep 08 2011 Good point. It looks like shell throws if the return value is an error c...
- Timon Gehr (4/37) Sep 08 2011 It seems DMD actually writes the error messages to stdout anyways.
- Justin Whear (8/8) Sep 08 2011 For posterity's sake, the "correct" (and much more complicated way) is t...
- Steven Schveighoffer (5/13) Sep 08 2011 This is the plan for the revamped version of std.process, which is held ...
- Andrej Mitrovic (2/4) Sep 08 2011 That's good news, thanks. I'll try the various pipe/redirect methods soo...
- Regan Heath (8/20) Sep 09 2011 I have, somewhere, a windows (or perhaps cross platform?)
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.
Sep 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.
Sep 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.
Sep 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.
Sep 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:Well, if shell throws, it will not return, and the output will not be assigned to res.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.
Sep 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:Well, if shell throws, it will not return, and the output will not be assigned to res.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.
Sep 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:It seems DMD actually writes the error messages to stdout anyways. This will stop shell from throwing: auto res = shell("dmd bla.d | cat");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:Well, if shell throws, it will not return, and the output will not be assigned to res.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.
Sep 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
Sep 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
Sep 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.
Sep 08 2011
On Thu, 08 Sep 2011 16:33:49 +0100, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote: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.I have, somewhere, a windows (or perhaps cross platform?) pipestream/subprocess implementation. But, this was for an older version of D/phobos and may not now compile. I'll have a look for it tonight, or later today (as, hopefully we'll have internet at home this afternoon). -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Sep 09 2011