I'd like to edit my .bashrc so that every command executed on the shell is piped to something, for example:
$ sudo apt update _________________ < sudo apt update > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
I have managed something rather similar, but not entirely:
$ bash $ exec > >(cowsay) $ echo "Hello AU!" $ exit _______ < Hello AU! > ------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
It is not the desired result, as it only happens after exiting the current shell.
It's mainly for fun/learning purposes.
You can adapt your method a bit. Instead of piping to
cowsaydirectly, read output till a delimiting character, send that output to
cowsay, then print that character after every command:
Here, I'm using the ASCII NUL character. You can use something else that's unlikely to appear in command output.
This will print after the prompt, so the output will be ugly:
Note that this will break any command which tries complex output or has a text user interface (think command line editors, pagers, etc.).
Assuming you already know what
exec > >(...)does, the part in the process substitution is:
while IFS= read -d '' -r line; do ... done: this is a fairly common idiom for reading data delimited by the ASCII NUL character:
IFS=sets the IFS to the empty string, which disables field splitting
\in the input specially (so,
\nfor example, is read as
\nand not converted to the newline character).
-d ''is the way to tell
readto read until the NUL character
So the whole thing loops over input in NUL-delimited sections, while preserving the contents of the input as much as possible.
if [[ -n $line ]]; then ... fi; done- only act if the input read so far is not empty.
echo; printf "%s\n" "$line" | cowsay;- print a leading empty line, so that the cowsay output doesn't clash with the prompt, and then send the input read so far to cowsay.
printfis more reliable and safer than