Як я передаю кожну команду, надану оболонці?


14

Я хотів би відредагувати .bashrc так, щоб кожна команда, виконана на оболонці, передавалася на щось, наприклад:

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

Мені вдалося щось досить схоже, але не повністю:

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

Це не бажаний результат, оскільки це відбувається лише після виходу з поточної оболонки.

Це в основному для розваг / навчання.


Використання -nпрапора до cowsayкорисно; це змушує зберігати пробіли.
wjandrea

Відповіді:


12

Ви можете трохи адаптувати свій метод. Замість того, щоб прямувати cowsayбезпосередньо, читайте висновок до символу, що розмежовує, надішліть його cowsay, а потім надрукуйте цей символ після кожної команди

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

Тут я використовую символ ASCII NUL. Ви можете використовувати щось інше, що навряд чи з’явиться у командному виході.

Це буде надруковано після підказки, тож вихід буде некрасивим:

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

Зверніть увагу, що це порушить будь-яку команду, яка намагається складно вивести або має текстовий інтерфейс користувача (редактори командних рядків, пейджери тощо).

Якщо припустити, ви вже знаєте, що exec > >(...) робить, участь у процесі заміни:

  • while IFS= read -d '' -r line; do ... done: це досить поширена ідіома для читання даних, розмежованих символом ASCII NUL:

    • IFS= встановлює IFS на порожній рядок, що вимикає розбиття поля
    • -rперешкоджає readлікуванню \на вході спеціально (так, \nнаприклад, читається як\n і не перетворюються в символ нового рядка).
    • -d ''це спосіб сказати readчитати до символу NUL

    Таким чином, вся справа перетворюється на введення в розділах, визначених NUL, при цьому максимально зберігаючи вміст введення.

  • if [[ -n $line ]]; then ... fi; done - діяти лише в тому випадку, якщо введений до цього часу вхід не порожній.
  • echo; printf "%s\n" "$line" | cowsay;- надрукуйте провідний порожній рядок, щоб вихід корів не зіткнувся із запитом, а потім надішліть прочитаний вхід до коровай. printfнадійніше і безпечніше echo.

1
Як моя підказка має LINEBREAK в ньому Cowsay вихід робить зіткнення з другою частиною - можливо також встановити запит на що - то , не відволікаючись?
десерт

16

Ви можете trapі зловживати DEBUGсигналом Баша :

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

Приклад виконання

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

Однак це все ж виконає команду після цього. Завдяки ilkkachu я знайшов такий спосіб:

$ shopt -s extdebug
$ trap 'bash -c "$BASH_COMMAND" | cowsay; false' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.