Você pode adaptar seu método um pouco. Em vez de canalizar para cowsay
diretamente, leia a saída até um caractere delimitador, envie essa saída para cowsay
e imprima esse caractere após cada comando:
exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
PROMPT_COMMAND='printf "$ export LC_ALL=C
$ exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
$ PROMPT_COMMAND='printf "exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
PROMPT_COMMAND='printf "$ export LC_ALL=C
$ exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
$ PROMPT_COMMAND='printf "%pre%"'
$ ls
$
______________________________________
/ Desktop Documents Downloads Music \
| Pictures Public Templates Videos
\ examples.desktop /
--------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
$ echo foo
$
______
< foo >
------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
"'
"'
$ ls
$
______________________________________
/ Desktop Documents Downloads Music \
| Pictures Public Templates Videos
\ examples.desktop /
--------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
$ echo foo
$
______
< foo >
------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
"'
Aqui, estou usando o caractere ASCII NUL. Você pode usar outra coisa que provavelmente não aparece na saída do comando.
Isso será impresso após o prompt, então a saída será feia:
%pre%Observe que isso quebrará qualquer comando que tente uma saída complexa ou tenha uma interface de usuário de texto (imagine editores de linha de comando, pagers, etc.).
Supondo que você já saiba o que o exec > >(...)
faz, a parte na substituição do processo é:
-
while IFS= read -d '' -r line; do ... done
: este é um idioma bastante comum para ler dados delimitados pelo caractere ASCII NUL:-
IFS=
define o IFS para a cadeia vazia, o que desativa a divisão de campos -
-r
impede queread
trate\
na entrada especialmente (por isso,\n
, por exemplo, é lido como\n
e não convertido para o caractere de nova linha). -
-d ''
é a maneira de informarread
para ler até o caractere NUL
Assim, a coisa toda faz um loop sobre a entrada em seções delimitadas por NUL, enquanto preserva o conteúdo da entrada o máximo possível.
-
-
if [[ -n $line ]]; then ... fi; done
- só age se a entrada lida até agora não estiver vazia. -
echo; printf "%s\n" "$line" | cowsay;
- imprime uma linha vazia inicial, de modo que a saída do cowsay não colida com o prompt, e então envia a entrada lida até agora para o cowsay.printf
é mais confiável e seguro queecho
.