
現在の会社の元従業員が書いたスクリプトを解読しようとしたところ、多くのスクリプトで、以下に示すように、いくつかのコマンドに変数を割り当てる次のステートメントに遭遇しました。
CAT=cat
GREP=grep
SED=sed
スクリプトの後半では、通常のコマンドの代わりに次の変数が使用されていることがわかります。
$GREP -v "^#" `dirname $0`/abcdfilename | while read line
do
<some loop operations>
done
直接使用するのではなく、この変数を使用する意味がわかりませんgrep
。私の質問は次のとおりです:
- このように grep または sed (このケース) を実行することに意味はあるでしょうか?
- これは、他の人が理解しにくくなるように意図的にスクリプトを書こうとした結果でしょうか?
- それとも、これは単にスクリプトの不具合の例なのでしょうか?
答え1
システム上の標準コマンドには、さまざまな実装があります。Solaris 10 以前では、/bin/sh
古い Bourne シェルと/usr/xpg4/bin/sh
POSIX 準拠のシェルがあります。または、OSX では、 を呼び出すときに BSD sed がありsed
、 を呼び出すときに GNU sed がありますgsed
。スクリプトで使用する実装を選択できます。
したがって、変数を使用したときにスクリプト内の実装を変更するのが簡単になります。GNU sed が必要な場合:
SED=gsed
変数を使用しない場合は、sed
スクリプト内の のすべての出現箇所を置き換える必要があります。これは簡単に実行できますが、プログラミングの悪い習慣と見なされます。
答え2
スクリプト全体で繰り返し使用するほぼすべてのものを変数にするとよいという議論があります。そうすれば、それを一度再定義するだけで、スクリプトの残りの部分に波及させることができるからです。
基本的に同じことは単純な sed 検索/置換でも実行できると主張する人もいるかもしれませんが、意図せずに何かを誤って置換することはそれほど難しくないため、多くのユーザーは検索/置換を警戒しています。
実際、私は既存のバージョンよりもこの改善を提案します:
GREP=${GREP:-/bin/grep}
つまり、GREPはユーザーがシェルで設定した値に設定されます。設定されていない場合は、/bin/grepに設定されます。
この方法では、ユーザーは 'grep' をその場で上書きできます。
$ export GREP=/bin/fgrep
$ ./path/to/script.sh
答え3
これはおそらく時期尚早な最適化の例です。
その機械にはいくつの選択肢があるか、あるいはどれでも機械は持っているsed、グレップ、 そしてawk? 普遍的な平均は 1.0 に近いと思います。特定のマシンで 2 つの選択肢がある場合、実装が異なり、スクリプトが PATH にあるバージョンでは失敗し、他のバージョンでは機能する確率はどれくらいでしょうか。そのような場合、解決策はスクリプトを変更することでしょうか、それとも PATH を変更することでしょうか。スクリプトを変更することが解決策であると判明した場合、少なくとも 1 つの呼び出しが見つかる確率はどれくらいでしょうか。グレップの代わりに$GREP? 間接的な処理の必要性がなくなり、必要になったとしても意図したとおりに機能しなくなります。
私は文化と戦うつもりはありません。もしあなたのお店に$GREPまたは翻訳: 翻訳済みあるいは単にグレップ、私はうまくやっていくためにおそらく従うでしょう。そうでなければ、KISS: 必要が生じるまで間接的な表現は避けてください。