내 스크립트 .bash_functions.test
에서 선택한 다음 스크립트를 호출했습니다 ..bash_functions
# vim: set syn=sh noet:
mp4Options_BIS="-movflags +frag_keyframe"
declare -A audioExtension=( [libspeex]=spx [speex]=spx [opus]=opus [vorbis]=ogg [aac]=m4a [mp3]=mp3 [mp2]=mp2 [ac3]=ac3 [wmav2]=wma [pcm_dvd]=wav [pcm_s16le]=wav )
function test1 {
echo "=> mp4Options_BIS = $mp4Options_BIS"
echo "=> audioExtension = ${audioExtension[*]}"
}
함수 를 실행하면 test1
다음이 표시됩니다.
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
마지막으로 스크립트를 다시 가져와서 test1
함수를 다시 실행하면 다음이 표시됩니다.
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
실제로 저는 Source
첫 번째 소스 호출뿐만 아니라 내장 함수와 두 번째 소스 호출에서도 source
내 함수를 사용하고 있습니다 .
$ grep -r .bash_functions.test
.bash_functions:source $initDir/.bash_functions.test
$ type Source
Source is a function
Source ()
{
test "$debug" -gt 0 && time source "$@" && echo || source "$@"
}
무슨 일이 일어나는가?
$ Source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
$ source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
왜 이런 식으로 작동합니까?
답변1
declare
/ typeset
없이 -g
유형을 설정하는 것 외에도 현재 범위의 변수를 선언합니다.
여기서는 함수 내에서 실행 declare -A audioExtension=(...)
되기 때문에 변수가 해당 함수에 대해 로컬로 선언되므로 일단 반환되면 해당 정의가 손실됩니다.Source
audioExtension
Source
typeset -Ag audioExtension=(...)
항상 전역 범위에서 변수를 선언 하도록 변경할 수 있습니다 ( typeset -g
변수가 로컬이 되는 것을 방지하는 zsh/mksh/yash와 다릅니다(유형/속성 및 값만 업데이트). 함수가 Source
다른 함수 자체 호출에서 시작될 때; 보다bash 대 zsh: 범위 지정 및 `typeset -g`더 알아보기).
ksh93
대신 사용하는 경우 ( 연관 배열 구문을 빌린 bash
쉘 ) 함수를 다음과 같이 정의할 수 있습니다.bash
Source
Source() {
...
}
반대:
function Source {
...
}
ksh93에서 func() cmd
Bourne 스타일 구문을 사용하여 정의된 함수에는 로컬 범위가 없습니다 function func {
.변화 없는로컬 범위(여기서만하나글로벌 범위 및하나로컬 범위의 스택이 아닌 로컬 함수별 범위).
(및 로컬 범위가 있는 다른 셸) 에는 bash
새 범위를 도입하지 않고 기능을 갖는 유사한 방법이 없습니다. alias
비슷한 대안을 사용할 수 있습니다 .
shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
alias Source='time source'
else
alias Source=source
fi
(코드가 확장되면 별칭도 확장됩니다.읽다, 아직 아님처형된).
기능적 접근 방식과 비교하면 기능적 차이가 있습니다.
Source ./myfile | other-cmd
우리는 둘 다 시간을 측정할 것이며 source myfile
, 함수 메서드에서 while other-cmd
으로 확장되므로 time source ./myfile | other-cmd
timing 을 전달할 것입니다 source ./myfile
.
사용해도 아무런 효과가 없습니다( time 키워드 대신 독립 실행형 유틸리티가 source=(time source); "${source[@]}" /some/file
호출됩니다 ).time
bash