최근에 당신을 발견했어요Bash 배열에 빈 문자열을 전달할 수 없습니다.. 빈 문자열 값을 배열에 삽입하려고 하기 때문에 이는 까다롭습니다.
그러나 Bash 완료 변수 COMP_WORDS에 null 값이 포함될 수 있다는 것을 확인했습니다.
디버깅 옵션을 활성화하여 이를 설명하기 위해 더미 완성 스크립트를 작성했습니다.
1 #!/bin/bash
2 _comp() {
3 set -xv
4 for i in ${!COMP_WORDS[@]}; do
5 echo "<${COMP_WORDS[$i]}>"
6 done
7 set +xv
8 local cur=${COMP_WORDS[$COMP_CWORD]}
9
10 local arr=(apple banana mango pineapple)
11 COMPREPLY=()
12 COMPREPLY=($(compgen -W "${arr[*]}" -- $cur))
13
14 }
15
16 complete -F _comp dummy
파일을 받고 다음을 입력하면:
dummy apple banana
그런 다음 사과와 바나나 사이의 중간 공간(아래 밑줄)으로 커서를 다시 이동하면...
dummy apple _ banana
그런 다음 탭을 클릭하면 4개의 배열 요소 'dummy' 'apple' 'banana'를 표시하는 생성된 디버그에서 다음과 같은 출력을 얻습니다.
for i in '${!COMP_WORDS[@]}'
+ echo '<dummy>'
<dummy>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<apple>'
<apple>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<>'
<>
+ for i in '${!COMP_WORDS[@]}'
+ echo '<banana>'
<banana>
따라서 COMP_WORDS 배열은 분명히 일종의 빈 문자열을 저장할 수 있습니다. 흥미롭게도 이것은아니요이는 인덱스 대신 배열 요소에 액세스하는 일반 for 루프를 사용하는 경우 발생합니다. 즉, 디버그 섹션의 for 루프를 다음과 같이 변경하면...
for i in ${COMP_WORDS[@]}; do
echo "<$i>"
done
그런 다음 'dummy' 'apple' 'banana' 세 개의 배열 요소만 표시하는 다음과 같은 디버그 출력을 얻습니다.
for i in '${COMP_WORDS[@]}'
+ echo '<dummy>'
<dummy>
+ for i in '${COMP_WORDS[@]}'
+ echo '<apple>'
<apple>
+ for i in '${COMP_WORDS[@]}'
+ echo '<banana>'
<banana>
- -를 사용하여 배열의 길이를 에코해 보았습니다. ${#COMP_WORDS[@]}
이 입력의 경우 길이가 4로 표시됩니다. 따라서 여기에는 분명히 4개의 요소가 포함되어 있으며 그 중 하나는 빈 문자열입니다.
이것은 나에게 매우 이상한 행동처럼 보입니다. 내 질문은 두 가지입니다.
일반 배열이 분명히 빈 문자열을 저장할 수 없는데 COMP_WORDS 배열이 빈 문자열을 저장할 수 있다는 설명은 무엇입니까?
일반 for 루프를 사용할 때는 빈 문자열을 볼 수 없지만 인덱스로 배열 요소에 액세스할 때는 볼 수 있는 이유는 무엇입니까?
답변1
""
빈 문자열과 NULL 문자를 혼동하고 있는 것 같습니다 \0
. 그들은 다르다. 배열과 변수에 빈 문자열을 사용할 수 있습니다.
$ a=(aa "" "b")
$ echo "${#a[@]}"
3
$ printf -- '- %s\n' "${a[@]}"
- aa
-
- b
$ for i in "${a[@]}"; do
> printf '%s\n' "$i"
> done
aa
b
일부조건식Bash에서는 문자열이 비어 있는지 테스트하는 것도 허용됩니다.
-z 문자열
True if the length of string is zero.
-n 문자열 문자열
True if the length of string is non-zero.
당신은 또한 볼 수 있습니다언제 큰따옴표가 필요합니까?