シェルに与えられた各コマンドをパイプするにはどうすればよいですか?


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 ''readNUL文字まで読むように指示する方法です

    したがって、入力の内容を可能な限り保持しながら、全体がNUL区切りセクションの入力をループします。

  • if [[ -n $line ]]; then ... fi; done -これまでに読み込まれた入力が空でない場合にのみ機能します。
  • echo; printf "%s\n" "$line" | cowsay;-カウセイの出力がプロンプトと衝突しないように、先頭の空行を出力し、それまでに読み取った入力をカウセイに送信します。printfは、より信頼性が高く安全ですecho

1
私のプロンプトには改行が含まれているため、カウセイの出力 2番目の部分と衝突します。
デザート

16

あなたはtrapbashの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 |
                ||     ||
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.