Я хотел бы отредактировать мой .bashrc так, чтобы каждая команда, выполняемая в оболочке, была направлена на что-то, например:
$ sudo apt update
_________________
< sudo apt update >
-----------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Мне удалось что-то довольно похожее, но не полностью:
$ bash
$ exec > >(cowsay)
$ echo "Hello AU!"
$ exit
_______
< Hello AU! >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Это не желаемый результат, так как это происходит только после выхода из текущей оболочки.
Это в основном для развлечения / обучения.
Вы можете немного адаптировать свой метод. Вместо непосредственного подключения к 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;
- выведите начальную пустую строку, чтобы вывод cowsay не конфликтовал с подсказкой, а затем отправьте введенные данные до сих пор в cowsay. printf
является более надежным и безопасным, чем echo
. Вы можете trap
и злоупотребить сигналом DEBUG
bash:
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 |
|| ||