bash 4.3을 사용하면 수동 동작과 실제 동작 사이에 차이가 있는 것 같습니다.
unset string # just to be sure
declare string # $? is 0 afterwards
declare -p string # fails, 'string: not found'
printf %b "${string-unset}" "\n" # consequently, yields unset
내장 선언/조판 매뉴얼 섹션에는 선언 시 할당이 필요한 선언이 없습니다. 대신에 이 declare [...] [...] name[=value]
기호는 이것이 합법적이어야 함을 의미합니다.
내가 무엇을 놓치고 있습니까? 변수를 "설정"한다는 것이 무엇을 의미하는지에 대한 정의입니까? 최소한 "설정 해제"라는 용어를 사용하는 설명서의 "매개 변수 확장" 섹션을 잘못 읽었습니까? 아니면 이것은 단지 버전별 이상한 점입니까?
답변1
bash 버전 3.2 이하의 경우 순서는 다음과 같습니다.
$ declare string; declare -p string
print declare -- string=""
는 변수가 빈 문자열로 설정되었음을 보여줍니다.
버전 4.1, 4.2, 4.3에서는 이 변수가 아무 것도 설정되지 않아 실제로 오류가 발생합니다.
$ declare string; declare -p string
bash: declare: string: not found
Bash 4.4에서 해결되었습니다.
$ declare string; declare -p string
declare -- string
이는 문자열이 선언되었지만 값이 할당되지 않았음을 의미합니다(null도 아님).
답변2
실제로 매개변수/변수의 의미에 대한 가정은 다음과 같습니다.설정되지 않음OP의 내용이 정확하지 않습니다.
man bash
변수를 특수 유형의 매개변수로 정의합니다. 따라서 변수에 대한 정보는 일반 매개변수만을 다루는 부분에 위치하는 경우가 있습니다.
변수를 설명하는 일반 용어
변수의 특성과 상태를 기술하는 용어변수에 관한 Wikipedia 기사.
- 신고현황: 메모리가 예약되어 있고 이름이 존재합니다.
- 초기화 상태: 1.에 추가로 값을 할당합니다. (선언 직후)
- 초기화되지 않은 상태: 값이 정의되지 않음, 초기값이 설정되지 않음(선언만 발생)
- 유효하지 않은value: 초기화되지 않은 변수를 나타내기 위해 일부 프로그래밍 언어에서 반환되는 예약된/특수 값
Bash 매뉴얼의 변수 관련 항목
- 상태 설정: "매개변수에 값이 할당된 경우 매개변수가 설정된 것입니다."
- 상태가 설정되지 않음, 모호함은 일반 용어에 따라 "초기화되지 않은 상태"에 있는 변수뿐만 아니라 존재하지 않거나 더 이상 존재하지 않는 변수에 적용되는 것으로 보입니다: "...설정되지 않은 매개변수에 대한 bash 테스트..." [매개변수 확장 단락 ]
- 빈/빈 문자열- NULL: "매개변수에 값이 할당된 경우 매개변수가 설정됩니다. 빈 문자열이 유효한 값입니다."
- 내장 설정되지 않음- 변수를 "설정 해제"하는 명령(예
unset string
: "각 이름에 대해 해당 변수를 삭제합니다..." [SHELL BUILTIN COMMANDS 섹션, 'unset' 단락]) - 내장 선언- 예
declare -p string
: "-p 옵션은 각 이름의 속성과 값을 표시합니다. [SHELL BUILTIN COMMANDS 섹션, '선언'/'Typesetting' 단락]
원래 질문을 바꿔서 대답하세요.
질문은 다음과 같이 더 정확하게 표현되어야 합니다.초기화되지 않은 bash 변수와 존재하지 않는 변수를 구별하는 방법은 무엇입니까?"
이에 대한 대답은 다음과 같습니다.
이것에 대해 혼동하지 마십시오
unset
내장존재하는 변수를 제거하고 그 안에 있는 변수를 삭제합니다.상태가 설정되지 않음Bash 용어로 선언되지 않았거나 값 없이 선언되었습니다.declare
내장 명령은 값 없이 선언된 변수에 대해 bash 4.3과 bash 4.4에서 일관되지 않게 작동합니다.$ # bash 4.3 $ unset string; declare string; declare -p string; echo $? bash: declare: string: not found 1 $ # bash 4.4 $ unset string; declare string; declare -p string; echo $? declare -- string 0
따라서 사용 중인 단일 변수 이름을 테스트하는 이 방법은 보편적이지 않지만 최신 bash 버전에서는 작동하는 것 같습니다.
안타깝게도 매개변수 확장은 존재하지 않는 변수와 초기화되지 않은 변수를 구별하는 데 도움이 되지 않습니다. 두 경우 모두 동일한 변수에 포함되어 있기 때문입니다.상태가 설정되지 않음:
$ declare string; echo ${string-UNSET} # `string` exists, empty UNSET $ unset string; echo ${string-UNSET} # `string` does not exist UNSET
불행하게도 조건 연산자는
-v
VARNAME이 존재하는지 여부를 나타내지 않고 "쉘 변수 VARNAME이 설정되었는지(값이 할당되어 있는지)"를 테스트하는 [매뉴얼 섹션 CONDITIONAL EXPRESSIONS]에 도움이 되지 않습니다.$ unset string; ! [ -v string ] && echo "unused" unused $ declare string; ! [ -v string ] && echo "unused" unused
관련 주제
토론에서는 매개변수/변수 상태 및 값과 관련된 용어 혼란과 bash 세부 정보에 중점을 둡니다.