web-dev-qa-db-ja.com

色付きgrep出力:GREP_OPTIONSではなくエイリアスではありません

grepのカラー出力が必要です。

.... だが

  • 戦略1:GREP_OPTIONS。しかし、これは非推奨です。 http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html を参照してください
  • 戦略2:GREP_COLORSは一見したところ解決策のように見えますが、これは別のことをします。
  • 戦略3:エイリアス。 xargsはエイリアスを評価しないため、これはfind ... | xargs grepでは機能しません。
  • 戦略4:単純なラッパースクリプトを記述します。いいえ、これはあまりにも汚いため、解決するよりも問題が多いと思います。
  • 戦略5:ソースコードにパッチを適用する
  • 戦略6:grep開発者に連絡し、GREP_OPTIONSの交換を依頼する
  • 戦略簡単で簡単:...これがありません。私は見当もつかない。

これを解決するには?

助けてくれてありがとう!

...しかし、私は賞金を与えることができません

私を失礼、傲慢、侮辱的、虐待的と呼びます....

回避策しか表示されません-解決策はありません。質問に答える回答はありませんでした。

ご清聴ありがとうございました。

10
guettli

OPがオプションが不適切であると述べた理由のいくつかは、実際には根拠がありません。ここでは、OPの戦略4を使用してどのような効果があるかを示します。


ほとんどのディストリビューションでは、grep/bin(標準)または/usr/bin(OpenSUSEなど)にインストールされ、デフォルトのPATH/usr/local/binまたは/binの前に/usr/binを含みます。つまり、/usr/local/bin/grep

#!/bin/sh
exec /bin/grep --color=auto "$@"

ここで、/bin/shは、ディストリビューションによって提供されるPOSIX互換シェルであり、通常はbashまたはdashです。 grep/usr/binにある場合は、

#!/bin/sh
exec /usr/bin/grep --color=auto "$@"

このスクリプトのオーバーヘッドは最小限です。 execステートメントは、スクリプトインタープリターがgrepバイナリーに置き換えられることを意味します。つまり、grepが実行されている間、シェルはメモリに残りません。したがって、唯一のオーバーヘッドは、スクリプトインタープリターの1つの余分な実行、つまり実時間での小さな待ち時間です。レイテンシはほぼ一定で(grepshが既にページキャッシュにあるかどうか、および使用可能なI/O帯域幅の量によってのみ異なります)、grepの実行時間や処理するデータの量には依存しません。

それで、その待ち時間、つまりラッパースクリプトによって追加されるオーバーヘッドはどのくらいですか?

確認するには、上記のスクリプトを作成して実行します。

time /bin/grep --version
time /usr/local/bin/grep --version

私のマシンでは、前者は(多数の実行にわたって)0.005秒のリアルタイムで実行されますが、後者は0.006秒のリアルタイムで実行されます。したがって、私のマシンでラッパーを使用するオーバーヘッドは、呼び出しごとに0.001秒(またはそれ以下)です。

これは重要ではありません。

また、多くの一般的なアプリケーションとユーティリティが同じアプローチを使用しているため、これについて「汚い」ことは何も見落としています。お使いのマシンの/bin/usr/binでそのようなリストを表示するには、次のコマンドを実行します。

file /bin/* /usr/bin/* | sed -ne 's/:.*Shell script.*$//p'

私のマシンでは、上記の出力には、egrepfgrepzgrepwhich7zchromium-browserldd、およびxfigが含まれます。ラッパースクリプトに依存するためにディストリビューション全体を「ダーティ」と見なさない限り、そのようなラッパースクリプトを「ダーティ」と見なす理由はありません。


問題に関しては、そのようなラッパースクリプトは以下を引き起こす可能性があります。

(スクリプトではなく)人間のユーザーのみが、出力が端末への出力の場合にデフォルトでカラーサポートになっているバージョンのgrepを使用している場合、ラッパースクリプトの名前は、colorgrepまたはcgrep、またはOPが適合するものとすることができます。

これにより、grepの動作がまったく変更されないため、考えられるすべての互換性の問題が回避されます。


ラッパースクリプトでgrepオプションを有効にするが、新しい問題を回避する方法で:

GREP_OPTSがサポートされていない場合でも(すでに非推奨であるため)、ラッパースクリプトを簡単に書き換えて、カスタムGREP_OPTIONSをサポートできます。このように、ユーザーはexport "GREP_OPTIONS=--color=auto"または類似のものを自分のプロファイルに追加するだけです。 /usr/local/bin/grepは次に

#!/bin/sh
exec /bin/grep $GREP_OPTIONS "$@"

$GREP_OPTIONSは引用符で囲まれていないため、ユーザーは複数のオプションを指定できます。

私のシステムでは、time /usr/local/bin/grep --versionを空にして、またはGREP_OPTIONSを指定してGREP_OPTIONS=--color=autoを実行すると、以前のバージョンのラッパースクリプトと同じくらい高速です。つまり、通常のgrepよりも実行に通常1ミリ秒長くかかります。

この最後のバージョンは、私が個人的に使用することをお勧めするバージョンです。


要約すると、OPの戦略4:

  • grep開発者が推奨するエリア

  • 実装するのは簡単です(2行)

  • わずかなオーバーヘッドがあります(この特定のラップトップでの呼び出しごとに1ミリ秒の追加レイテンシ。各マシンで簡単に確認できます)

  • GREP_OPTSサポートを追加するラッパースクリプトとして実装できます(非推奨/サポートされていないGREP_OPTIONSを置き換えるため)

  • スクリプトまたは既存のユーザーにまったく影響を与えない(colorgrep/cgrepとして)実装可能

これはすでにLinuxディストリビューションで広く使用されている手法であるため、「ダーティー」ではなく一般的な手法です。

別個のラッパー(colorgrep/cgrep)として実装した場合、grepの動作にまったく影響しないため、新しい問題を作成できません。 GREP_OPTSのサポートを追加するラッパースクリプトとして実装する場合、GREP_OPTS=--color=autoを使用すると、デフォルトの--color=autoを上流に追加する場合とまったく同じリスク(既存のスクリプトに関する問題)が発生します。したがって、これが「解決するよりも多くの問題を作成する」というコメントは完全に正しくありません。追加の問題は作成されません。

13
Nominal Animal

GREP_OPTIONS変数は廃止予定です。grepがスクリプトのどこかで呼び出され、スクリプトが変数からの代替オプションで機能しない場合、問題が発生する傾向があります。 grepのラッパースクリプトを作成すると、同じ問題が発生します別の名前を付けない限り

$ cat ~/bin/cgrep
#!/bin/sh
exec grep --color=always "$@"
$ find … -exec cgrep … {} +

または、お気に入りのオプションを変数に保存します。 zsh以外のシェルでは、オプションにワイルドカード文字(\[*?)ですが、それ以外の場合は、引用符で囲まれていない変数を使用して、引数付きのコマンドを取得できます。

cgrep=(grep --color=always)
find … -exec $cgrep … {} +

GNUおよびBSD grepはディレクトリツリーを再帰的に処理できるため、ほとんどの場合findgrepと組み合わせて使用​​する必要がなくなります。

あなたが最初の戦略で提供するドキュメントは言う:

代わりにエイリアスまたはスクリプトを使用してください。たとえば、grepがディレクトリ ‘/ usr/bin’にある場合、$ HOME/binをPATHの先頭に追加して、以下を含む実行可能スクリプト$ HOME/bin/grepを作成できます。

#! /bin/sh
export PATH=/usr/bin
exec grep --color=auto --devices=skip "$@"

したがって、エイリアスが不可能な場合は、ラッパースクリプトが唯一の方法です。

3
stderr

最も簡単な方法は、エイリアスを使用することです(戦略3)。 xargsコマンドを本当に気にしている場合でも、bash関数でオーバーライドできます。

alias grep='grep --color'
xargs() {
    local args
    for ((i=1; i<=$#; i++))
    do
            if [[ "-E -L -P -I -s -d" == *"${!i}"* ]]; then
                    ((i=i+1))
            Elif [[ ${!i:0:1} != "-" ]]; then
                    if [[ ${!i} == "grep" ]]; then
                            args="--color"
                    fi
                    /usr/bin/xargs ${@:1:i} $args ${@:i+1}
                    return;
            fi
    done
}

しかし、これはgrepチームが推奨するソリューションであると思われるラッパーコマンドを使用するよりも優れています。

/usr/local/bin/grep:

#!/bin/bash
/bin/grep --color "$@"

私の考えでは、grep開発者チームに連絡して、grepの色を有効にするGREP_OPTIONS変数の簡単な置き換えを提供するよう依頼する必要があります。いくつかの環境変数に。

彼らがデフォルトでcolorオプションを有効にするのは、またはGREP_COLORSが設定されている場合は非常に簡単です。

1
Adam

これは、@ NominalAnimalによる上位の回答からの解決策ですが、警告には通常のgrep: ...が(/bin/grep: ...ではなく)含まれています。

#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"
0
Kirill Bulygin