(defmacro pipe (&rest commands) (setf commands (nreverse commands)) (labels ((sub (cmd rest) `(uiop:process-info-output (uiop:launch-program ,cmd :output :stream ,@(when rest `(:input ,(sub (car rest) (cdr rest)))))))) `(uiop:run-program ,(pop commands) :output :string :input ,(sub (car commands) (cdr commands))))) (pipe "foo" "ls" "sort" "diff")