¿Cómo canalizo cada comando dado al shell?

14

Me gustaría editar mi .bashrc para que cada comando ejecutado en el shell se canalice a algo, por ejemplo:

 $ sudo apt update
  _________________
< sudo apt update >
 -----------------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

He logrado algo bastante similar, pero no del todo:

$ bash
$ exec > >(cowsay)
$ echo "Hello AU!"
$ exit
 _______
< Hello AU! >
 -------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

No es el resultado deseado, ya que solo ocurre después de salir del shell actual.

Es principalmente para fines de diversión / aprendizaje.

M. Becerra
fuente
Usar la -nbandera para cowsayes útil; hace que conserve el espacio en blanco.
wjandrea

Respuestas:

12

Puedes adaptar tu método un poco. En lugar de canalizar cowsaydirectamente, lea la salida hasta un carácter delimitador, envíe esa salida a cowsay, luego imprima ese carácter después de 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 "\0"'

Aquí, estoy usando el carácter ASCII NUL. Puede usar algo más que es poco probable que aparezca en la salida del comando.

Esto se imprimirá después de la solicitud, por lo que el resultado será feo:

$ 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 "\0"'
$ ls
$
 ______________________________________
/ Desktop Documents Downloads Music    \
| Pictures Public Templates Videos
\ examples.desktop                     /
 --------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

$ echo foo
$
 ______
< foo  >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Tenga en cuenta que esto interrumpirá cualquier comando que intente resultados complejos o tenga una interfaz de usuario de texto (piense en editores de línea de comandos, buscapersonas, etc.).

Suponiendo que ya sabe lo que exec > >(...)hace, la parte en la sustitución del proceso es:

  • while IFS= read -d '' -r line; do ... done: este es un idioma bastante común para leer datos delimitados por el carácter ASCII NUL:

    • IFS= establece el IFS en la cadena vacía, lo que deshabilita la división de campos
    • -revita que se readtrate especialmente \en la entrada ( \npor ejemplo, se lee como \ny no se convierte al carácter de nueva línea).
    • -d ''es la forma de decir readque lea hasta que el carácter NUL

    Por lo tanto, todo se repite sobre la entrada en secciones delimitadas por NUL, mientras se preserva el contenido de la entrada tanto como sea posible.

  • if [[ -n $line ]]; then ... fi; done - solo actúa si la entrada leída hasta ahora no está vacía.
  • echo; printf "%s\n" "$line" | cowsay;- imprima una línea vacía inicial, para que la salida de cowsay no entre en conflicto con la solicitud, y luego envíe la entrada leída hasta ahora a cowsay. printfes más fiable y más seguro que echo.
muru
fuente
1
Como mi pronta tiene un salto de línea en el que la salida cowsay no choque con la segunda parte de él - tal vez también configurar el símbolo de algo que no distrae?
postre
16

Puedes trapabusar de la DEBUGseñal de bash :

trap 'bash -c "$BASH_COMMAND" | cowsay' DEBUG

Ejecución de ejemplo

$ trap 'bash -c "$BASH_COMMAND" | cowsay' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
AU is awesome!

Sin embargo, esto seguirá ejecutando el comando después. Gracias a ilkkachu encontré una forma de evitarlo :

$ shopt -s extdebug
$ trap 'bash -c "$BASH_COMMAND" | cowsay; false' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
postre
fuente