Hi, A lot of times the most useful information when an external program returns an error is the stderr output. However, I can't figure out any way to get this without setting :ignore-error-status to T. In particular I feel things would be strictly better if every invocation of the form: (run-program ... :error-output t) Acted more like: (let ((result (multiple-value-list (run-program :error-output t :ignore-error-status t)))) (when (not (zerop (caddr result))) (cerror ...)) (values-list result)) The former prints no output to *error-output* in the event of non-zero return, but the latter prints all the output. There may be a better way of doing this (including the error file or output in the condition object perhaps?), so I'm open to alternatives. Any thoughts? -Jason
I did a bit more digging and found some interesting behavior on sbcl. Whether or not the output is propagated to a stream in the event of an error is dependant on shell vs. exec: (uiop:run-program "echo hi >&2; false" :error-output t) ; No output (uiop:run-program '("/bin/sh" "-c" "echo hi >&2; false" ) :error-output t) ; "hi\n" on *error-output* -Jason On 10:44 Fri 09 Sep , Jason Miller wrote:
Hi,
A lot of times the most useful information when an external program returns an error is the stderr output. However, I can't figure out any way to get this without setting :ignore-error-status to T.
In particular I feel things would be strictly better if every invocation of the form:
(run-program ... :error-output t)
Acted more like:
(let ((result (multiple-value-list (run-program :error-output t :ignore-error-status t)))) (when (not (zerop (caddr result))) (cerror ...)) (values-list result))
The former prints no output to *error-output* in the event of non-zero return, but the latter prints all the output.
There may be a better way of doing this (including the error file or output in the condition object perhaps?), so I'm open to alternatives. Any thoughts?
-Jason
On 9 Sep 2016, at 20:35, Jason Miller <jason@milr.com> wrote:
I did a bit more digging and found some interesting behavior on sbcl.
Whether or not the output is propagated to a stream in the event of an error is dependant on shell vs. exec:
(uiop:run-program "echo hi >&2; false" :error-output t) ; No output (uiop:run-program '("/bin/sh" "-c" "echo hi >&2; false" ) :error-output t) ; "hi\n" on *error-output*
-Jason
Dear list (I’ve already talked to Jason in person on IRC so that he can savely ignore this e-mail), the difference in behaviour seen here:
(uiop:run-program "echo hi >&2; false" :error-output t) ; No output (uiop:run-program '("/bin/sh" "-c" "echo hi >&2; false" ) :error-output t) ; "hi\n" on *error-output*
boils down to the use of %run-program vs. %system as a result of the snippet (when (stringp command) (unless force-shell-suppliedp #-(and sbcl os-windows) ;; force-shell t isn't working properly on windows as of sbcl 1.2.16 (setf force-shell t))) in run-program. What currently happens is that we have code of the form (let (exit-code) (with-program-output … (setf exit-code (%check-result (%wait-process-result))))) This means: If %check-result yields a condition, the with-program-output will not complete. But there’s no good reason for that. All %check-result needs is the exit-code and we keep that around anyway, so that we can just move %check-result out of the with-program-output block. This should not have any negative side effects I’m aware of and leave e.g. :error-output, if it’s a stream, in a deterministic state. I’ve put up a merge request here: https://gitlab.common-lisp.net/asdf/asdf/merge_requests/8 and would welcome comments. Elias PS: There are also a few other merge requests at https://gitlab.common-lisp.net/asdf/asdf/merge_requests
participants (2)
-
Elias Pipping
-
Jason Miller