web-dev-qa-db-ja.com

コマンド列の出力のパイピング

Lsの出力をカラーで取得するためにlolcatを使用しています。これを行うには、/ usr/bin/lsを/ usr/bin/lsslssにコピーし(エイリアスが$ *または$ @を受け入れることができないため無限ループを回避するため)、次の関数を追加しました。

ls(){ lsslss $* | lolcat; }から.bashrc

問題は、私がlsを使用すると、パイプが一度に各ファイルをパイプ処理するため、次のような長いリストとして表示されることです。

enter image description here

このようなテーブルの代わりに:

enter image description here

これをテーブルに変更するには、出力を列コマンドにパイプします。しかし、それを行うと、長いリストに戻ります(おそらく列が行に変更するのではなく、フォーマットするだけなので)

私は最初にやろうとしていました:

ls(){ lsslss $* | columns | lolcat; }

とにかく、|を使用する代わりに生の出力をパイプ処理する方法はあるのかと思っていました。列の出力をlolcatにパイプできるようにするには?

前もって感謝します。私の質問の言葉遣いが悪い、または理解しにくい場合は、申し訳ありません。ほとんどの場合、既に質問されているので、頻繁に質問を投稿することはありません。

5
cohill Oniell

@dessertの答えを拡張すると、色付きのlsバージョンを実際のlsと同じように(うまくいけば?)すべてのケースで動作させるには、もう少し作業が必要です。問題は、lsが解析されることを意図しておらず、人間の目のみを目的としていることです。その目的のために、それは環境に応じてそれがどのように機能するかを強く適応させます。端末に接続されているか、パイプに出力されているか。

まず、再帰を回避するために個別の_/bin/lsslss_実行可能ファイルは必要ありません。シェル組み込みcommandを使用して、ディスクから実行可能ファイルを呼び出し、同じ名前のシェル関数またはエイリアスを無視します。

次に、_$*_はすべての関数引数を単一の文字列として提供します。引用符が付けられていないため、Word分割の対象になります。スペースを含む引数がある場合、これは驚くほど間違った結果をもたらす可能性があります。常に_"$@"_を使用します。これにより、すべての引数が最初に指定されたとおりに保持され、連結や分割は行われません。

そして3番目に、定義を配置する場所によっては、lsがすでにエイリアスである場合、関数を定義する構文ls () { ... ;}が機能しないことがあります。これは、エイリアス展開が最初に発生し、構文エラーが発生するためです。その前にfunctionと書いて明示的な構文を使用します。

次に、ls '_-C_フラグを使用して、列の出力を手動で有効にします。

_function ls() { command ls -C "$@" | lolcat ;}
_

ただし、それを行って出力をlolcat(またはその他)にパイプ処理すると、ターミナルの全幅を使用しなくなり、せいぜい80列しか使用しなくなります。これは、標準出力が端子に直接接続されていないと、端子の幅を検出できないためです。ただし、シェルはターミナルをまだ認識しており、COLUMNS変数に検出した幅を設定します。ただし、この変数はデフォルトではエクスポートされないため、lsにはこの値は表示されません。次のようなこのコマンドのためだけに手動で渡すことができます:

_function ls() { COLUMNS="$COLUMNS" command ls -C "$@" | lolcat ;}
_

ここで、常に正しい幅を取得する必要がありますが、実際にlsを他の何かにパイプしたい場合はどうなりますか?最初に言ったように、lsは決して解析されるべきではないため、通常はそれを行うべきではありません。時にはそれでもまだ便利な場合があります(そして、一部のスクリプトは悲しいことにそれに依存する場合があります)。そのため、少なくとも元の動作を維持するようにしましょう。今のところ、常に出力として列を取得します。 _ls | cat_。 (lolcatはターミナルまたはパイプに出力するかどうかもチェックし、後者の場合は色をオフにするので、もう色付けされていません)

パイプされている場合はプレーンな実数lsを使用する関数にチェックを追加し、ターミナルビュー専用の派手なRainbowカラムバージョンを追加します。標準出力(ファイル記述子1)が端末/ TTYであるかどうかは、単に_[[ -t 1 ]]_で確認できます。

_function ls() { 
    if [[ -t 1 ]] ; then COLUMNS="$COLUMNS" command ls -C "$@" | lolcat ; else command ls "$@" ; fi
}
_

lsからの特別な/異なる動作が予想されるすべてのケースをキャッチするのに十分だと私は思うので、あなたの関数は端末で直接見たときにのみ色を追加し、そうでなければ何も変更しません。

14
Byte Commander

出力がパイプされるとき、lsは列のリストを無効にします。 -Cオプションを使用して、明示的に有効にします。

ls(){ COLUMNS="$COLUMNS" command ls -C "$@" | lolcat; }

COLUMNS="$COLUMNS"は、COLUMNS変数を現在のターミナルの幅に正しく設定します。デフォルトは80です。ターミナルウィンドウのサイズを変更して、出力を比較してください。 command lsは、エイリアスと関数を無視し、その実行可能ファイルがどこにあってもlsを呼び出します。引用するために"$@"を使用したことに注意してください Bash Hackers Wiki

["$@"]は、最初に設定され、スクリプトまたは関数に渡されたすべての位置パラメーターを反映します。位置パラメーターを再利用して別のプログラム(ラッパースクリプトなど)を呼び出す場合は、二重引用符"$@"を使用します。
まあ、ただ言いましょう:ほとんど常に引用符が必要です"$@"

4
dessert