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: ==== #!/bin/sh echo stderr 1>&2 ====