set -u
(に対応するset -o nounset
)を追加しましたが、.bashrc
変数が設定されていないというエラーにより、一部のタブのオートコンプリートが失敗します。一例はgit
オートコンプリートです。
これはオートコンプリートのバグですか、それともgit
一般的に対話型端末で使用するのは悪い考えですか?set -u
オートコンプリート機能を損なうことなく自分自身を保護する他の方法はありますか?
(Windows / cygwinとRHELで「git bash」を使用して同じ問題が発生しました。)
答え1
set -u
Bourneシェルまたはより具体的にはset -o nounset
Kornシェル(どちらもPOSIX)からのものは、コード内の初期化された変数のオタナの使用を検出するためのプログラミングツールに近いです。
これはプログラミングスタイルの選択です。一度設定すると、コードに設定されていない変数を逆参照させることはできません。つまり、コードを別々に書く必要があります。
たとえば、次の操作を実行できません。
if [ -n "$TERM" ]; then
echo running in a terminal
fi
useの代わりにnounset
withの問題を解決する必要があります。${TERM-}
$TERM
[[ -v TERM ]]
errexit
いくつかはorfailglob
や他のほとんどの他のオプションと組み合わせて使用されます。pipefail
これはシェルの動作を変更し、コード作成者はコードを調整する必要があります。
インタラクティブシェルでは、他の人が書いたコードを使用しない限り問題はありません。
問題は、bashは、サードパーティemulate -L
関数が独自のコードに対してローカルで合理的なオプション基準を明示的に要求できるzshと同じではないことです。
zshでは、完了コードは通常次のことを行います。
some-completion-function() {
emulate -L zsh # default set of options in the zsh emulation set locally
set -o extendedglob -o errreturn # additional local options as needed
code here not impacted by the users options
}
bashには同等の機能はありませんが、bash
has(ashの最新バージョンlocal -
)は設定されているオプションのローカル範囲を設定できますがset
。shopt
同等のものがないため、emulate
すべてのオプションをデフォルト値にハードコードする必要があり、そのリストはbashのバージョンによって変わります。
bash_completion(bash自体とは別のプロジェクト)は、デフォルトオプションをグローバルに(それ自体だけでなく)変更し、ユーザーがそれを変更しないと予想することに言及する価値があります。たとえば、extglob
とを設定しますprogcomp
。
たとえば、オプションを一時的に設定したり、以前の設定を変数に保存したり、後で復元してオプションをぎこちなく設定したりすることがverbose
ありますnoglob
。nullglob
Bash と zsh にはコードの解析方法に影響を与えるオプションもあるため、完了コード(またはサードパーティのコード)がロードされた後に設定する必要があります。 zshのほとんどの完了コードは次のとおりです。自動ロード初めて使用するとき、自動ロードはユーザーのオプションやエイリアス(オプション-z
も含む)とは無関係に実行できますが、bashにはそれに対応する機能はありません。-U
autoload
したがって、デフォルトが変更されると、bashが完了しないようにする多くのオプションがあることがわかります(、、、、noglob
などnounset
)errexit
。 IIRCで値を変更すると、問題が発生する可能性があります(または少なくとも慣れている場合)。これらのいくつかはbash_completionのバグと見なすことができますが、ほとんどの場合これを非難することはできません。問題は、bashがさまざまなオプションセットの要件に対処できるツールを持っていないためです。errreturn
failglob
$IFS
したがって、オプションを変更すると、シェルで使用されているサードパーティのコードの一部が失敗する可能性があることに注意してください。