-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Many shell commands leverage the terminal processing of special characters like ^H (backspace) and ^M (newline) to perform some special formatting, like rewriting text in place.
This is often seen when a progress bar is displayed by the command. Try rsync, wget, curl, your package manager...
Running these commands in a Lisp REPL often makes for pages of garbage output, making them practically un-runnable.
An easy way around this is to ask uiop:launch-program to write the output to a stream, then to process the stream for special characters.
Here is an example that processes ^H and ^M:
(let ((process (uiop:launch-program "test.sh" :output :stream :error-output :output)))
(labels ((decode-process-output-to-stream (process output-stream)
(alex:when-let ((line (read-line (uiop:process-info-output process) nil nil)))
(let ((lines (str:split "
" line)))
(write-string
(sera:ensure-suffix
(str:join
(string #\n ewline)
(mapcar (lambda (line)
(reduce (lambda (&optional string char)
(if (eq char #\�)
(subseq string 0 (max 0 (1- (length string))))
(str:concat string (string char))))
line
:initial-value ""))
lines))
(string #\n ewline))
output-stream))
(decode-process-output-to-stream process output-stream))))
(decode-process-output-to-stream process t)))with foo.sh:
#!/bin/sh
printf "backspace test: begin-ERR\b\b\bOR\b\bend\n\bline0"
echo
printf "newline test: line1\nline2"
echo
printf "CRLF newline test: line3\r\nline4"
echoIt would be super useful to integrate this to CMD. I suggest adding a dynamic variable where the user could specify the output translators. When NIL, no translation would happen.
Thoughts?