如何管理给shell的每个命令?

我想编辑我的.bashrc,以便在shell上执行的每个命令都通过管道输出,例如:

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

我管理的东西相似但不完全:

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

这不是理想的结果,因为它只在退出当前shell后发生。

它主要用于娱乐/学习目的。

你可以调整一下你的方法。 而不是直接管道到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 while IFS= read -d '' -r line; do ... done :这是读取由ASCII NUL字符分隔的数据的相当常见的习惯用法:

    • IFS=将IFS设置为空字符串,这将禁用字段拆分
    • -r防止read在输入中特别处理\ (因此, \n例如,读取为\n而不转换为换行符)。
    • -d ''是告诉读读直到NUL字符的方法

    因此整个事件在NUL分隔的部分中循环输入,同时尽可能地保留输入的内容。

  • if [[ -n $line ]]; then ... fi; done if [[ -n $line ]]; then ... fi; done – 仅在目前为止读取的输入不为空时才动作。
  • echo; printf "%s\n" "$line" | cowsay; – 打印一个前导空行,以便cowsay输出不会与提示冲突,然后将输入读取到目前为止发送到cowsay。 printfecho更可靠,更安全。

你可以trap和滥用bash的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 | || ||