![ZSH의 변수 범위: 함수 내에서 전역 변수에 액세스하는 방법은 무엇입니까?](https://linux55.com/image/205181/ZSH%EC%9D%98%20%EB%B3%80%EC%88%98%20%EB%B2%94%EC%9C%84%3A%20%ED%95%A8%EC%88%98%20%EB%82%B4%EC%97%90%EC%84%9C%20%EC%A0%84%EC%97%AD%20%EB%B3%80%EC%88%98%EC%97%90%20%EC%95%A1%EC%84%B8%EC%8A%A4%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
계속해서 확장되는 .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
결국 취소하는 대신 무시됩니다.