現在、会社の以前の従業員が作成したいくつかのスクリプトを復号化しようとして、多くのスクリプトが次の特定のコマンドに変数を割り当てる次のステートメントを見つけました。
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
します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、grepとアッ?私はコンセンサス平均が1.0に近いと確信しています。特定のマシンで2つの選択肢があると、実装の違いによってPATHのバージョンでスクリプトが失敗し、他のバージョンで動作する可能性はどのくらいですか?これが発生した場合、ソリューションがスクリプトやパスを変更する可能性は高くなりますか?スクリプトを変更することが答えであることが判明した場合、少なくとも1回の呼び出しを見つける可能性はどのくらいですか?grep変える$GREP?デッキの積み重ねには間接参照は必要なく、そのようにしても期待どおりに機能しません。
私は文化と戦わないでしょう。店舗に優先事項がある場合$GREPまたは/usr/bin/grepそうでなければgrep、一緒に行って元気に過ごせます。それ以外の場合は、KISS:必要になるまで間接使用を避けてください。