Bash 맵파일 배열 수가 다릅니다.

Bash 맵파일 배열 수가 다릅니다.

나는 다음을 수행했습니다.

mapfile -t array < <(commands)

개행으로 구분된 출력을 생성 합니다 commands.

그런 다음 결과에 따라 배열에 아무것도 없으면 종료하고, 그렇지 않으면 계속합니다.

[[ "${#array[@]}" -eq 0 ]] && exit

...

문제는 이 조건이 결코 충족되지 않는다는 것이다. commands아무 것도 반환 하지 않으면 ${#array[@]}0 대신 1을 반환하기 때문입니다.

그러나 다음과 같이 배열을 할당하면 개수가 정확합니다.

array=($(commands))

내 테스트:

$ declare -a array
$ array=($(echo))
$ echo ${#array[@]}
0
$ unset array
$ mapfile -t array < <(echo)
$ echo ${#array[@]}
1

왜?


array=($(commands))처음에는 이 형식을 사용했지만 shellcheck대신 이 형식을 사용하는 것이 좋습니다 mapfile.

GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

답변1

명령에 아무것도 인쇄되지 않으면 다음과 같은 결과가 나타납니다.

$ mapfile -t array < <(printf ''); echo "num: ${#array[@]}"; declare -p array
num: 0
declare -a array=()

빈 줄을 인쇄하면 다음과 같은 결과를 얻게 됩니다.

$ mapfile -t array < <(echo); echo "num: ${#array[@]}"; declare -p array
num: 1
declare -a array=([0]="")

빈 줄은 빈 요소를 생성하는데, 이는 매우 적절합니다.

프로그램에서 이와 같은 빈 줄이 생성되고 이를 방지할 수 없는 경우 grep다음을 사용하여 이를 제거할 수 있습니다. 또는 단일 배열 요소가 비어 있는지 확인하십시오.

빈 줄을 제거하려면 다음 명령을 사용하십시오 grep.

$ mapfile -t array < <(echo | grep .); echo "num: ${#array[@]}"; declare -p array
num: 0
declare -a array=()

빈 요소가 있는지 확인하십시오.

$ mapfile -t array < <(echo);
$ if [[ "${#array[@]}" = 0 || "${#array[@]}" = 1 && "${array[0]}" = "" ]]; then 
    echo "empty list or only one empty element"; 
 fi
empty list or only one empty element

존재하다

array=($(commands))

명령 대체 결과가 토큰화되어 후행 공백도 제거되기 때문에 다릅니다. 그리고 줄을 공백으로 나눕니다. (명령 대체 자체도 후행 줄 바꿈을 제거하지만 여기서는 중요하지 않습니다.)

관련 정보