Come installo ogni comando dato alla shell?


14

Vorrei modificare il mio .bashrc in modo che ogni comando eseguito sulla shell sia reindirizzato a qualcosa, ad esempio:

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

Ho gestito qualcosa di piuttosto simile, ma non del tutto:

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

Non è il risultato desiderato, poiché si verifica solo dopo essere usciti dalla shell corrente.

È principalmente per scopi di divertimento / apprendimento.


Usare la -nbandiera per cowsayè utile; lo fa preservare gli spazi bianchi.
wjandrea,

Risposte:


12

Puoi adattare un po 'il tuo metodo. Invece di eseguire il piping cowsaydirettamente, leggi l'output fino a un carattere delimitante, invia l'output a cowsay, quindi stampa quel carattere dopo ogni 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"'

Qui sto usando il carattere ASCII NUL. Puoi usare qualcos'altro che è improbabile che appaia nell'output del comando.

Questo verrà stampato dopo il prompt, quindi l'output sarà brutto:

$ 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 |
                ||     ||

Si noti che ciò interromperà qualsiasi comando che provi un output complesso o abbia un'interfaccia utente di testo (si pensi agli editor della riga di comando, ai cercapersone, ecc.).

Supponendo che tu sappia già cosa exec > >(...)fa, la parte nella sostituzione del processo è:

  • while IFS= read -d '' -r line; do ... done: questo è un linguaggio abbastanza comune per leggere i dati delimitati dal carattere ASCII NUL:

    • IFS= imposta l'IFS sulla stringa vuota, che disabilita la divisione dei campi
    • -rimpedisce readdi trattare \in modo specifico l'input (quindi, \nad esempio, viene letto come \ne non convertito nel carattere di nuova riga).
    • -d ''è il modo di dire readdi leggere fino al carattere NUL

    Quindi il tutto passa sopra l'input nelle sezioni delimitate da NUL, preservando il più possibile il contenuto dell'input.

  • if [[ -n $line ]]; then ... fi; done - agire solo se l'ingresso letto finora non è vuoto.
  • echo; printf "%s\n" "$line" | cowsay;- stampare una riga vuota iniziale, in modo che l'output di Cowsay non si scontri con il prompt, quindi inviare l'input letto finora a Cowsay. printfè più affidabile e più sicuro di echo.

1
Poiché il mio prompt contiene un'interruzione di riga, l'output di Cowsay si scontra con la seconda parte di esso - forse imposta anche il prompt su qualcosa di non distrazione?
dessert

16

Puoi trape abusare del DEBUGsegnale di bash :

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

Esempio di esecuzione

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

Tuttavia, ciò eseguirà comunque il comando in seguito. Grazie a ilkkachu ho trovato un modo per aggirare questo:

$ shopt -s extdebug
$ trap 'bash -c "$BASH_COMMAND" | cowsay; false' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.