For future reference, here's a script that one can use to check (unfortunately, only with one's own eyes) if an implementation behaves as expected.
SBCL e.g. does (with the change for consistency in place). Here's the output of the script:
==== UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :OUTPUT :INTERACTIVE stdout UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :OUTPUT :INTERACTIVE :FORCE-SHELL T stdout UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stdout.sh") :OUTPUT :INTERACTIVE stdout UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :OUTPUT :INTERACTIVE stdout UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :OUTPUT :INTERACTIVE :FORCE-SHELL T stdout UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stdout.sh" :OUTPUT :INTERACTIVE stdout
UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stdout.sh") :OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stdout.sh" :OUTPUT NIL
UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT :INTERACTIVE UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stdout.sh") :ERROR-OUTPUT :INTERACTIVE UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT :INTERACTIVE UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stdout.sh" :ERROR-OUTPUT :INTERACTIVE
UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stdout.sh") :ERROR-OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stdout.sh" :ERROR-OUTPUT NIL
UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :OUTPUT :INTERACTIVE stderr UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :OUTPUT :INTERACTIVE :FORCE-SHELL T stderr UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stderr.sh") :OUTPUT :INTERACTIVE UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :OUTPUT :INTERACTIVE stderr UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :OUTPUT :INTERACTIVE :FORCE-SHELL T stderr UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stderr.sh" :OUTPUT :INTERACTIVE
UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stderr.sh") :OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stderr.sh" :OUTPUT NIL
UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT :INTERACTIVE UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stderr.sh") :ERROR-OUTPUT :INTERACTIVE UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT :INTERACTIVE UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stderr.sh" :ERROR-OUTPUT :INTERACTIVE
UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM ("./stderr.sh") :ERROR-OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT NIL UIOP/RUN-PROGRAM:RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT NIL :FORCE-SHELL T UIOP/RUN-PROGRAM:LAUNCH-PROGRAM "./stderr.sh" :ERROR-OUTPUT NIL ====
And this is the script:
==== (load "common-lisp/asdf/build/asdf.lisp")
(defmacro verbose-do ((f &rest args)) `(progn (format t "~s ~{~s~^ ~}~%" ',f (list ,@args)) (,f ,@args)))
(loop :for script :in ‘(“./stdout.sh" “./stderr.sh") :do (loop :for (specifier . mode) :in '((:output . :interactive) (:output . nil) (:error-output . :interactive) (:error-output . nil)) :do (progn (verbose-do (uiop:run-program (list script) specifier mode)) (verbose-do (uiop:run-program (list script) specifier mode :force-shell t)) #-clisp (uiop:wait-process (verbose-do (uiop:launch-program (list script) specifier mode)))
(verbose-do (uiop:run-program script specifier mode)) (verbose-do (uiop:run-program script specifier mode :force-shell t)) #-clisp (uiop:wait-process (verbose-do (uiop:launch-program script specifier mode))) (terpri))))
(uiop:quit 0) ====
With these two helpers:
- stdout.sh:
==== #!/bin/sh
echo stdout ====
- stderr.sh:
echo stderr 1>&2 ====
For future reference, here's a script that one can use to check (unfortunately, only with one's own eyes) if an implementation behaves as expected.
SBCL e.g. does (with the change for consistency in place). Here's the output of the script:
==== PROGRAM: RUN-PROGRAM ("./stdout.sh") :OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM ("./stdout.sh") :OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stdout.sh") :OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stdout.sh" :OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stdout.sh" :OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stdout.sh" :OUTPUT :INTERACTIVE
UIOP/RUN-
stdout
UIOP/RUN-
stdout
UIOP/RUN-
stdout
UIOP/RUN-
stdout
UIOP/RUN-
stdout
UIOP/RUN-
stdout
UIOP/RUN- PROGRAM: RUN-PROGRAM ("./stdout.sh") :OUTPUT NIL PROGRAM: RUN-PROGRAM ("./stdout.sh") :OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stdout.sh") :OUTPUT NIL PROGRAM: RUN-PROGRAM "./stdout.sh" :OUTPUT NIL PROGRAM: RUN-PROGRAM "./stdout.sh" :OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stdout.sh" :OUTPUT NIL
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN- PROGRAM: RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stdout.sh") :ERROR-OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stdout.sh" :ERROR-OUTPUT :INTERACTIVE
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN- PROGRAM: RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT NIL PROGRAM: RUN-PROGRAM ("./stdout.sh") :ERROR-OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stdout.sh") :ERROR-OUTPUT NIL PROGRAM: RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT NIL PROGRAM: RUN-PROGRAM "./stdout.sh" :ERROR-OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stdout.sh" :ERROR-OUTPUT NIL
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN- PROGRAM: RUN-PROGRAM ("./stderr.sh") :OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM ("./stderr.sh") :OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stderr.sh") :OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stderr.sh" :OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stderr.sh" :OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stderr.sh" :OUTPUT :INTERACTIVE
stderr
UIOP/RUN-
stderr
UIOP/RUN-
UIOP/RUN-
stderr
UIOP/RUN-
stderr
UIOP/RUN-
UIOP/RUN- PROGRAM: RUN-PROGRAM ("./stderr.sh") :OUTPUT NIL PROGRAM: RUN-PROGRAM ("./stderr.sh") :OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stderr.sh") :OUTPUT NIL PROGRAM: RUN-PROGRAM "./stderr.sh" :OUTPUT NIL PROGRAM: RUN-PROGRAM "./stderr.sh" :OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stderr.sh" :OUTPUT NIL
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN- PROGRAM: RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stderr.sh") :ERROR-OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT :INTERACTIVE PROGRAM: RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT :INTERACTIVE :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stderr.sh" :ERROR-OUTPUT :INTERACTIVE
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN- PROGRAM: RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT NIL PROGRAM: RUN-PROGRAM ("./stderr.sh") :ERROR-OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM ("./stderr.sh") :ERROR-OUTPUT NIL PROGRAM: RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT NIL PROGRAM: RUN-PROGRAM "./stderr.sh" :ERROR-OUTPUT NIL :FORCE-SHELL T PROGRAM: LAUNCH- PROGRAM "./stderr.sh" :ERROR-OUTPUT NIL
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
UIOP/RUN-
====
And this is the script:
==== lisp/asdf/ build/asdf. lisp")
(load "common-
(defmacro verbose-do ((f &rest args))
`(progn
(format t "~s ~{~s~^ ~}~%" ',f (list ,@args))
(,f ,@args)))
(loop
(: error-output . :interactive) (:error-output . nil))
(verbose- do (uiop:run-program (list script) specifier mode))
(verbose- do (uiop:run-program (list script) specifier mode :force-shell t))
(verbose- do
(uiop: launch- program
(list script) specifier mode)))
:for script :in ‘(“./stdout.sh" “./stderr.sh")
:do
(loop
:for (specifier . mode)
:in '((:output . :interactive) (:output . nil)
:do (progn
#-clisp (uiop:wait-process
#-clisp (uiop:wait-process
(uiop:quit 0)
====
With these two helpers:
- stdout.sh:
====
#!/bin/sh
echo stdout
====
- stderr.sh:
====
#!/bin/sh
echo stderr 1>&2
====