스크립트가 실행될 때 다른 오류 메시지로 채워지는 배열이 있습니다.
스크립트 끝이 비어 있지 않은지 확인하고 특정 조치를 취해야합니다.
이미 일반 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