[server] Bash에서 배열이 비어 있는지 확인하십시오.

스크립트가 실행될 때 다른 오류 메시지로 채워지는 배열이 있습니다.

스크립트 끝이 비어 있지 않은지 확인하고 특정 조치를 취해야합니다.

이미 일반 VAR처럼 처리하고 -z를 사용하여 확인하려고 시도했지만 작동하지 않는 것 같습니다. 배열이 비어 있는지 Bash에 있는지 확인하는 방법이 있습니까?



답변

배열이이라고 가정하면 $errors요소 개수가 0인지 확인하십시오.

if [ ${#errors[@]} -eq 0 ]; then
    echo "No errors, hooray"
else
    echo "Oops, something went wrong..."
fi


답변

이 경우 일반적으로 산술 확장을 사용합니다.

if (( ${#a[@]} )); then
    echo not empty
fi


답변

배열을 간단한 변수로 간주 할 수도 있습니다. 그런 식으로

if [ -z "$array" ]; then
    echo "Array empty"
else
    echo "Array non empty"
fi

또는 다른 쪽을 사용

if [ -n "$array" ]; then
    echo "Array non empty"
else
    echo "Array empty"
fi

해당 솔루션의 문제점은 배열이 다음과 같이 선언 된 경우 array=('' foo)입니다. 이러한 검사는 어레이가 비어있는 것으로보고되지만 명확하지는 않습니다. (@musiphil 감사합니다!)

사용 [ -z "$array[@]" ]하는 것도 해결책이 아닙니다. 중괄호를 지정하지 않으면 $array문자열 ( [@]이 경우 간단한 리터럴 문자열 임) 로 해석하려고 하므로 항상 거짓으로보고됩니다. “리터럴 문자열이 [@]비어 있습니까?” 분명히 아닙니다.


답변

나는 그것을 확인했다 bash-4.4.0:

#!/usr/bin/env bash
set -eu
check() {
    if [[ ${array[@]} ]]; then
        echo not empty
    else
        echo empty
    fi
}
check   # empty
array=(a b c d)
check   # not empty
array=()
check   # empty

그리고 bash-4.1.5:

#!/usr/bin/env bash
set -eu
check() {
    if [[ ${array[@]:+${array[@]}} ]]; then
        echo non-empty
    else
        echo empty
    fi
}
check   # empty
array=(a b c d)
check   # not empty
array=()
check   # empty

후자의 경우 다음 구성이 필요합니다.

${array[@]:+${array[@]}}

비어 있거나 설정되지 않은 배열에서 실패하지 않습니다. set -eu내가 평소처럼 한다면 보다 엄격한 오류 검사를 제공합니다. 에서 워드 프로세서 :

-이자형

단일 단순 명령 (단순 명령 참조), 목록 (목록 참조) 또는 복합 명령 (복합 명령 참조)으로 구성 될 수있는 파이프 라인 (파이프 라인 참조)이 0이 아닌 상태를 반환하면 즉시 종료하십시오. 실패한 명령이 while 또는 until 키워드 바로 뒤에 나오는 명령 목록의 일부인 if 문의 테스트 부분, && 또는 ||에서 실행 된 명령의 일부인 경우 쉘이 종료되지 않습니다. 마지막 && 또는 || 뒤에 오는 명령, 파이프 라인의 마지막 명령이지만 마지막 명령 또는 명령의 반환 상태가!로 반전 된 경우를 제외하고 list. -e가 무시되는 동안 명령이 실패하여 서브 쉘 이외의 복합 명령이 0이 아닌 상태를 리턴하면 쉘이 종료되지 않습니다. 설정된 경우 ERR의 트랩은 쉘이 종료되기 전에 실행됩니다.

이 옵션은 쉘 환경과 각 서브 쉘 환경에 별도로 적용되며 (명령 실행 환경 참조) 서브 쉘에서 모든 명령을 실행하기 전에 서브 쉘이 종료 될 수 있습니다.

-e가 무시되는 상황에서 복합 명령 또는 쉘 함수가 실행되면 복합 명령 또는 함수 본문 내에서 실행 된 명령은 -e가 설정되고 명령이 a를 반환하더라도 -e 설정의 영향을받지 않습니다. 실패 상태. 복합 명령 또는 쉘 함수가 -e가 무시되는 컨텍스트에서 실행되는 동안 -e를 설정하면 복합 명령 또는 함수 호출을 포함하는 명령이 완료 될 때까지 해당 설정이 적용되지 않습니다.

-유

파라미터 확장을 수행 할 때 특수 파라미터 ‘@’또는 ‘*’이외의 설정되지 않은 변수 및 파라미터를 오류로 취급하십시오. 오류 메시지가 표준 오류에 기록되고 비 대화식 쉘이 종료됩니다.

필요하지 않은 경우 자유롭게 생략하십시오 :+${array[@]}.

또한 [[여기에서 연산자 를 사용하는 것이 중요합니다 [.

$ cat 1.sh
#!/usr/bin/env bash
set -eu
array=(a b c d)
if [ "${array[@]}" ]; then
    echo non-empty
else
    echo empty
fi

$ ./1.sh
_/1.sh: line 4: [: too many arguments
empty


답변

당신은 빈 배열을 검색하도록하려면 요소 처럼,arr=("" "") 등, 빈과 동일arr=()

모든 요소를 ​​붙여넣고 결과 길이가 0인지 확인할 수 있습니다. (배열이 매우 클 수 있으면 배열 내용의 병합 사본을 작성하는 것은 성능에 이상적이지 않습니다. 그러나 그런 프로그램에 bash를 사용하지 않기를 바랍니다 …)

그러나 "${arr[*]}"의 첫 문자로 구분 된 요소로 확장됩니다 IFS. 따라서 IFS를 저장 / 복원 IFS=''하고이 작업을 수행해야 합니다. 그렇지 않으면 문자열 길이 == # 배열 요소 수-1 ( n요소 배열에 n-1구분 기호가 있음)을 확인해야합니다. 한 번에 하나씩 처리하려면 연결을 1만큼 채우는 것이 가장 쉽습니다.

arr=("" "")

## Assuming default non-empty IFS
## TODO: also check for ${#arr[@]} -eq 0
concat="${arr[*]} "      # n-1 separators + 1 space + array elements
[[ "${#concat}" -ne "${#arr[@]}" ]]  && echo not empty array || echo empty array

테스트 케이스 set -x

### a non-empty element
$ arr=("" "x")
  + arr=("" "x")
$ concat="${arr[*]} ";  [[ "${#concat}" -ne "${#arr[@]}" ]] && echo not empty array || echo empty array
  + concat=' x '
  + [[ 3 -ne 2 ]]
  + echo not empty array
not empty array

### 2 empty elements
$ arr=("" "")
  + arr=("" "")
$ concat="${arr[*]} ";  [[ "${#concat}" -ne "${#arr[@]}" ]] && echo not empty array || echo empty array
  + concat='  '
  + [[ 2 -ne 2 ]]
  + echo empty array
empty array

불행히도 이것은 실패합니다 arr=(): [[ 1 -ne 0 ]]. 따라서 실제로 빈 배열을 먼저 별도로 확인해야합니다.


또는IFS='' . 아마도 서브 쉘을 사용하는 대신 IFS를 저장 / 복원하고 싶을 것입니다. 서브 쉘에서 쉽게 결과를 얻을 수 없기 때문입니다.

# inside a () subshell so we don't modify our own IFS
(IFS='' ; [[ -n "${arr[*]}" ]] && echo not empty array || echo empty array)

예:

$ arr=("" "")
$ (IFS='' ; [[ -n "${arr[*]}" ]] && echo not empty array || echo empty array)
   + IFS=
   + [[ -n '' ]]
   + echo empty array
empty array

않습니다 와 함께 작동 arr=()– 그것은 여전히 빈 문자열입니다.


답변

제 경우 에는 공백이있을 수 있기 때문에 두 번째 대답으로 는 충분하지 않았습니다. 나는 함께했다 :

if [ "$(echo -ne ${opts} | wc -m)" -eq 0 ]; then
  echo "No options"
else
  echo "Options found"
fi


답변

이중 괄호를 사용하는 것이 좋습니다.

if [[ !${array[@]} ]]
then
    echo "Array is empty"
else
    echo "Array is not empty"
fi

이중 괄호 : https://stackoverflow.com/questions/669452/is-preferable-over-in-bash