What if we want to capture standard (and/or error) output in order to ignore it or post-process it ? It’s very simple, a little search and we’re good:

(let ((*standard-output* (make-string-output-stream)) (*error-output* (make-string-output-stream))) (apply function args) ;; anything (setf standard-output (get-output-stream-string *standard-output*))) (print-results standard-output))

and now in print-results we can print to standard output without being intercepted (and in our case, we’ll highlight some user-defined keywords).

Above, just don’t forget to get the output content with (get-output-stream-string *standard-output*) .

A thing to note is that if your app printed stuff on error output and standard output consecutively, now it will print all standard output as a single block.

(edit) Of course, with-output-to-string is simpler to capture one stream:

(setf standard-output (with-output-to-string (*standard-output*) (apply function args)))

edit 2, thanks to redditers:

Don’t bind standard-output directly; bind the string stream to a lexical, then bind *standard-output* to that:

(with-output-to-string (s) (let ((*standard-output* s)) (write-string "abc"))) -> "abc"

Now, let’s bind both *standard-output* and *standard-error* to s:

(with-output-to-string (s) (let ((*standard-output* s) (*standard-error* s)) (write-string "abc") (write-string "def" *standard-error*))) -> "abcdef"

Eliminate s and just bind *standard-output* and then tie *standard-error* to the same stream:

(with-output-to-string (*standard-output*) (let ((*standard-error* *standard-output*)) (write-string "abc") (write-string "def" *standard-error*))) --> "abcdef"

The conclusion stays: it’s handy and easy :)