Bash 배열에 빈 문자열이 포함될 수 없는 경우 이 배열은 이를 어떻게 수행합니까?

Bash 배열에 빈 문자열이 포함될 수 없는 경우 이 배열은 이를 어떻게 수행합니까?

최근에 당신을 발견했어요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개의 요소가 포함되어 있으며 그 중 하나는 빈 문자열입니다.

이것은 나에게 매우 이상한 행동처럼 보입니다. 내 질문은 두 가지입니다.

  1. 일반 배열이 분명히 빈 문자열을 저장할 수 없는데 COMP_WORDS 배열이 빈 문자열을 저장할 수 있다는 설명은 무엇입니까?

  2. 일반 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.

당신은 또한 볼 수 있습니다언제 큰따옴표가 필요합니까?

관련 정보