次のコードがあるとしましょう。
# Check if the color prompt is enabled and supported on this system
if [ -n "$force_color_prompt" ] && [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
GREEN="\033[1;32m"
DIM="\033[2m"
RESET="\033[00m"
fi
echo -e "Oh, ${GREEN}green${RESET} world, ${DIM}don't desert me now...${RESET}"
カラーサポートが有効になると、クールな色の線が表示されます。カラーサポートが有効になっていない場合、${GREEN}
同様の値は設定されず、テキストは通常の白と黒の背景で印刷されます。
このコードは、設定されていない変数が単に空の文字列として評価されるという事実に依存しています(私のテストではそうでした)。これにより、一部のシステムでエラーや問題が発生しますか、それとも存在しないすべての変数が発生しますか?いつも空の文字列として評価されますか?このメカニズムに頼ってはいけない理由はありますか?
ベストアンサー1
$FOO
あるいは、(等価)に拡張されると、存在しない変数は常に空の文字列として評価されます${FOO}
.
set -u
この変数を使用する前に、現在のシェルで誰かが呼び出されている場合は、その設定が有効になります。
-u引数実行時に設定されていない変数をエラーとして扱います。 さらに拡張してください。設定せずに拡張したい場合 変数が存在しない場合、シェルはエラーメッセージを出力します。 対話型、ゼロ以外の状態で終了します。
つまり、他の人が制御するスクリプトにソースとして提供されるように設計された関数を作成する場合は、設定されていない変数を使用するために編集証が必要になることがあります。それ以外のset -u
場合は、関数を呼び出す前に使用すると、スクリプトはエラーで終了します。設定されていない変数を初めて拡張しようとすると、メッセージが表示されます。
独自のスクリプトを作成する場合は、空の文字列に展開される未設定の変数に依存しても何の害もありません。
編集する- また考えてみてください。端末でterminfoカラー機能が利用可能かどうかに応じてすべてを条件付きにしているので、vt100の値をハードコードするのではなく、実際にterminfoを使用してシーケンスを生成するのはどうでしょうか?それは次のとおりです。
if [ -n "$force_color_prompt" ] && type tput &>/dev/null; then
GREEN="$(tput setaf 2)$(tput bold)"
DIM="$(tput dim)"
RESET="$(tput sgr0)"
fi
これは他の端末である程度移植性を提供することができます(もちろん、表示されたコードを使用しない端末の数は少なく減ります)。また、terminfo がどれだけ正確に定義されているかに応じて、一部のプラットフォームでは一部の機能が存在しない可能性があるため、一部の移植性を失う可能性があります。 YMMV。