Bagaimana cara menyalurkan setiap perintah yang diberikan ke shell?

14

Saya ingin mengedit .bashrc saya sehingga setiap perintah yang dijalankan pada shell disalurkan ke sesuatu, misalnya:

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

Saya telah mengelola sesuatu yang agak mirip, tetapi tidak sepenuhnya:

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

Ini bukan hasil yang diinginkan, karena hanya terjadi setelah keluar dari shell saat ini.

Ini terutama untuk tujuan belajar / bersenang-senang.

M. Becerra
sumber
Menggunakan -nbendera untuk cowsayberguna; itu membuatnya melestarikan spasi.
wjandrea

Jawaban:

12

Anda dapat sedikit menyesuaikan metode Anda. Alih-alih cowsaymengirim langsung, baca output hingga karakter pembatas, kirim output itu ke cowsay, lalu cetak karakter itu setelah setiap perintah:

exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
PROMPT_COMMAND='printf "\0"'

Di sini, saya menggunakan karakter ASCII NUL. Anda dapat menggunakan sesuatu yang lain yang tidak mungkin muncul di output perintah.

Ini akan mencetak setelah prompt, sehingga hasilnya akan jelek:

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

Perhatikan bahwa ini akan memecah perintah apa pun yang mencoba keluaran kompleks atau memiliki antarmuka pengguna teks (pikirkan editor baris perintah, pager, dll.).

Dengan asumsi Anda sudah tahu apa yang exec > >(...)dilakukan, bagian dari proses substitusi adalah:

  • while IFS= read -d '' -r line; do ... done: ini adalah ungkapan yang cukup umum untuk membaca data yang dibatasi oleh karakter ASCII NUL:

    • IFS= mengatur IFS ke string kosong, yang menonaktifkan pemisahan bidang
    • -rmencegah readmemperlakukan \dalam input secara khusus (jadi, \nmisalnya, dibaca sebagai \ndan tidak dikonversi ke karakter baris baru).
    • -d ''adalah cara untuk mengatakan readmembaca sampai karakter NUL

    Jadi semuanya loop atas input di bagian dibatasi-NUL, sambil mempertahankan isi input sebanyak mungkin.

  • if [[ -n $line ]]; then ... fi; done - hanya bertindak jika input yang dibaca sejauh ini tidak kosong.
  • echo; printf "%s\n" "$line" | cowsay;- cetak baris kosong di depan, sehingga output cowsay tidak berbenturan dengan prompt, dan kemudian mengirim input yang sudah dibaca sejauh ini ke cowsay. printflebih andal dan lebih aman daripada echo.
muru
sumber
1
Karena prompt saya memiliki linebreak di dalamnya, output cowsay tidak berbenturan dengan bagian kedua - mungkin juga mengatur prompt ke sesuatu yang tidak mengganggu?
hidangan penutup
16

Anda dapat trapdan menyalahgunakan DEBUGsinyal bash :

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

Contoh dijalankan

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

Namun, ini masih akan menjalankan perintah sesudahnya. Berkat ilkkachu saya menemukan jalan keluarnya :

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