引き続き拡張される.zshrc
ファイルがあって余裕がなくなったため、ファイルをモジュラーファイルに分けて、それぞれインポートして修正してみることにしました。これはほとんど機能しますが、変数にスコープの問題があるようです。
各モジュールファイルには、ファイル名に対応する関数が含まれています。例:(メインファイルから呼び出されます)nvm..zshrc
という関数が含まれています。.zshrc
zshrc_config_load_nvm {}
以下は、私が使用している設定の単純化された形式です。
デフォルトの.zshrcファイル
このファイルを徹底的にテストし、その中のすべてがうまく動作することに注意してください。
# Load all config files
# This method basically copied directly from the .oh-my-zsh.sh file.
for config_file ($ZSH_CUSTOM/*.zshrc(N)); do
# Skip self-inclusion
if [[ $config_file==".zshrc" || $config_file==".zshenv" ]]; then
continue
fi
# The (D) modifier will escape the path so it can be passed to `basename`
# without quotes. the second param in `basename` removes the file extension.
local handle=$(basename ${(D)config_file} .zshrc)
# If the file contains the expected callback function name ...
# The :t filter will remove the path and file extension.
if [[ $(command -v "zshrc_config_load_${handle}") ]]; then
# ... Add it to the list of functions to call.
ZSH_CONFIG_HANDLES+=($handle)
fi
# Each config file will call the register function above.
source $config_file
done
for handle ($ZSH_CONFIG_HANDLES); do
func="zshrc_config_load_${handle}"
# Call the function
$func
done
unset config_file handle func
nvm.zshrc
# This line is copied directly from the documentation.
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
# The callback function
function zshrc_config_load_nvm {
# Unable to access the $NVM_DIR variable in this scope.
source $NVM_DIR/nvm.sh --fast-reuse
# Error: /nvm.sh does not exist.
}
質問
export
他の関数のスコープからedグローバル変数にアクセスできますが、値をパラメータとして渡すのを防ぐにはどうすればよいですか?
~によるとこの回答渡すザイルズ「じゃあ邪悪なことはやめろ」...
export
[in] zshはzshの略語ですtypeset -gx
。ここで、属性はg
「グローバル」(関数のローカルとは反対)を意味し、属性はx
「エクスポートされた」(すなわち環境内)を意味する。
$NVM_DIR
...それで、変数を他の関数で使用できる必要があるとします。
答え1
関数は、サブシェルで設定されていないか、返された関数のいずれかでローカル変数として宣言されていない場合は、以前に設定した変数(エクスポートの有無にかかわらず)を表示できます。
問題は、コードの無関係なエラーが原因で発生します。
for config_file ($ZSH_CUSTOM/*.zshrc(N)); do # Skip self-inclusion if [[ $config_file==".zshrc" || $config_file==".zshenv" ]]; then continue fi
[[ somestring ]]
somestring
空の文字列でない場合は true を返します。$config_file==".zshrc"
明らかに空の文字列ではないので、testは値に関係なくtrueを返します$config_file
。したがって、ループは何もしません。
おそらくそういう意味でしょう。たとえ隠しファイルではないので、基本的にグローバル拡張に含まれず、とにかく始まって終わらないので[[ $config_file = .zsh(rc|env) ]]
少し無意味ではあるが。$config_file
.zshrc
.zshenv
$config_file
/path/to/zsh_custome/
.zshenv
.zshrc
if [[ $config_file -ef $0 ]] continue
$config_file
これが現在インポートされているスクリプトではないことを確認する方が合理的かもしれません。
その他の注意事項:
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
次のように書くことをお勧めします。
if (( $+XDG_CONFIG_HOME )); then
export NVM_DIR=$XDG_CONFIG_HOME/nvm
else
export NVM_DIR=~/.nvm
fi
存在する:
local handle=$(basename ${(D)config_file} .zshrc)
パラメータD
拡張フラグ(makeなど/home/you/file
)には~/file
意味がありません。
あなたが欲しいと思いますlocal handle=$config_file:t:r
(根~の尾ファイル)。
if [[ $(command -v "zshrc_config_load_${handle}") ]];
次のように書くことをお勧めします。
if command -v "zshrc_config_load_${handle}" >& /dev/null;
これにより、先端が割れるのを防ぐことができます。またはif (( $+functions[zshrc_config_load_${handle}] ));
…
...を実行する代わりに、関数または匿名関数の内部で使用できますvar=...
。unset var
local
function {
local var
...
}
外部範囲(または環境)にある場合は、$var
最終的にキャンセルするのではなく無視されます。