if [] (대괄호)의 "[: 너무 많은 인수"오류의 의미


211

다음 BASH 셸 오류의 의미를 수정하고 수정하는 간단한 간단한 리소스를 찾을 수 없으므로 연구 결과를 게시하고 있습니다.

오류:

-bash: [: too many arguments

Google에 적합한 버전 : bash open square bracket colon too many arguments .

컨텍스트 : 등호, 등호와 같은 간단한 비교 연산자를 사용하는 단일 대괄호의 if 조건은 다음과 같습니다.

VARIABLE=$(/some/command);
if [ $VARIABLE == 0 ]; then
  # some action
fi 

1
이 특정 오류를 생성 한 코드는 어디에 있습니까?
앤더슨 그린

답변:


353

당신이 경우 $VARIABLE공백이나 특수 문자가 포함 된 문자열 및 단일 대괄호가 사용 합니다 (바로 가기 인 test명령), 다음 문자열은 여러 단어 속으로 분할 할 수있다. 이들 각각은 별도의 인수로 취급됩니다.

따라서 하나의 변수가 여러 인수로 나뉩니다 .

VARIABLE=$(/some/command);  
# returns "hello world"

if [ $VARIABLE == 0 ]; then
  # fails as if you wrote:
  # if [ hello world == 0 ]
fi 

공백이나 다른 특수 문자를 포함하는 문자열을 내려 놓는 모든 함수 호출에 대해서도 마찬가지입니다.


쉬운 수정

변수 출력을 큰 따옴표로 묶어 하나의 문자열 (따라서 하나의 인수)로 유지하십시오. 예를 들어

VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
  # some action
fi 

그렇게 간단합니다. 그러나 변수가 빈 문자열이거나 공백 만 포함하는 문자열이 아니라고 보장 할 수 없으면 아래의 "또한주의하십시오 ..."로 건너 뛰십시오.


또는 대체 수정 은 이중 대괄호 ( new test명령 의 바로 가기)를 사용하는 것 입니다.

이것은 bash (및 korn 및 zsh)에만 존재하므로 /bin/shetc로 호출되는 기본 쉘과 호환되지 않을 수 있습니다 .

이는 일부 시스템에서는 콘솔에서 작동하지만cron 모든 구성 방법에 따라 와 같은 다른 곳에서는 호출되지 않을 수 있음을 의미 합니다.

다음과 같이 보일 것입니다 :

VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
  # some action
fi 

명령에 이와 같이 이중 대괄호가 포함되어 있고 로그에 오류가 발생하지만 콘솔에서 작동하는 경우 [[여기에서 제안 된 대안을 바꾸거나 스크립트를 실행할 때 [[aka 를 지원하는 쉘을 사용하는지 확인하십시오 new test.


또한 [: unary operator expected오류를 조심하십시오

"너무 많은 인수"오류가 표시되면 예상치 못한 출력을 가진 함수에서 문자열을 얻는 것입니다. 빈 문자열 (또는 모든 공백 문자열) 을 얻을 수도있는 경우 위의 "빠른 수정"을 사용하더라도 인수가 0으로 처리되고 실패합니다.[: unary operator expected

다른 언어에 익숙하다면 동일한 'gotcha'입니다. 변수의 내용이 평가되기 전에 이와 같은 코드로 효과적으로 인쇄되는 것을 기대하지 않습니다.

다음 [: too many arguments[: unary operator expected오류 와 오류를 모두 방지하는 예입니다 . 출력이 비어 있으면 기본값 (이 예에서는 0)으로 큰 따옴표로 묶인 출력을 바꾸십시오 .

VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
  # some action
fi 

(여기서 $ VARIABLE이 0이거나 비어있는 경우 작업이 수행됩니다. 당연히 다른 동작을 원하면 0 (기본값)을 다른 기본값으로 변경해야합니다)


최종 주 : 이후 [에 대한 바로 가기입니다 test모두가 위 또한 오류 사실이다 test: too many arguments(도하고 test: unary operator expected)


더 좋은 방법은 다음과 같습니다i=$(some_command); i=$((i)); if [ "$i" == 0 ] ...
Jo So

1
터미널을 통해 실행될 때 BASH를 인터프리터로 사용하는 셸 스크립트가 정상적으로 진행되지만 Crontab을 통해 실행될 때 이와 같은 오류가 발생하여 Postfix를 통해 로컬 전자 메일을 보내서이 오류를 알리는 문제가 발생하여 알았습니다. 특수 문자가있는 변수의 IF 큰 따옴표는 내 생명을 구했습니다. 감사합니다 :)!
ivanleoncz

13

두 개의 변수가 모두 비어 있는지 또는 비어 있지 않은지 테스트하려고 시도하면서 동일한 오류가 발생 하여이 게시물에 충돌했습니다 . 그것은 복합 비교로 밝혀졌습니다 -7.3. 다른 비교 연산자 – 고급 Bash 스크립팅 안내서 ; 그리고 나는 다음을 주목해야한다고 생각했다.

  • 내가 사용 -e은 처음에 "비우기"를 의미 생각; 그러나 이것은 "파일이 존재 함"을 의미합니다- -z변수 (문자열) 테스트에 사용
  • 문자열 변수는 인용해야합니다
  • 복합 논리 AND 비교의 경우 다음 중 하나입니다.
    • 이 사용 tests와 &&그들을 :[ ... ] && [ ... ]
    • 또는 -a단일 연산자를 사용하십시오 test.[ ... -a ... ]

다음은 작동하는 명령입니다 (디렉토리의 모든 txt 파일을 검색하고 grep찾은 파일을 덤프하면 두 단어가 모두 포함됨).

find /usr/share/doc -name '*.txt' | while read file; do \
  a1=$(grep -H "description" $file); \
  a2=$(grep -H "changes" $file); \
  [ ! -z "$a1" -a ! -z "$a2"  ] && echo -e "$a1 \n $a2" ; \
done

2013 년 8 월 12 일 수정 : 관련 문제 참고 사항 :

클래식 test(단일 대괄호 [)을 사용 하여 문자열 동등성을 검사 할 때는 반드시 "등호"연산자 사이에 공백 이 있어야합니다 .이 경우 단일 "등호" =부호 (두 개의 등호) 부호 ==는 동일 하게 받아 들여지는 것처럼 보입니다. 연산자도). 따라서 이것은 (자동) 실패합니다.

$ if [ "1"=="" ] ; then echo A; else echo B; fi 
A
$ if [ "1"="" ] ; then echo A; else echo B; fi 
A
$ if [ "1"="" ] && [ "1"="1" ] ; then echo A; else echo B; fi 
A
$ if [ "1"=="" ] && [ "1"=="1" ] ; then echo A; else echo B; fi 
A

...하지만 공간을 추가하면 모든 것이 좋아 보입니다.

$ if [ "1" = "" ] ; then echo A; else echo B; fi 
B
$ if [ "1" == "" ] ; then echo A; else echo B; fi 
B
$ if [ "1" = "" -a "1" = "1" ] ; then echo A; else echo B; fi 
B
$ if [ "1" == "" -a "1" == "1" ] ; then echo A; else echo B; fi 
B

bash 쉘 예제를 제공 할 수 ((A || B) && C)있습니까?
jww

질문 382642514964805
splaisan

예를 들어 루프가있는 경우 필요한 대괄호 안에 명령을 완전히 포함시키는 방법을 보여주지 않기 때문에 이것은 실제로 유용한 답이 아닙니다.
Timothy Swan

5

당신이 얻을 수있는 또 다른 시나리오 [: too many arguments또는 [: a: binary operator expected모든 인수에 대해 테스트를하려고하면 오류가있다"$@"

if [ -z "$@" ]
then
    echo "Argument required."
fi

전화 할 경우 올바르게 작동 foo.sh하거나 foo.sh arg1. 그러나과 같은 여러 인수를 전달 foo.sh arg1 arg2하면 오류가 발생합니다. [ -z arg1 arg2 ]유효한 구문이 아닌 로 확장 되었기 때문 입니다.

인수가 있는지 확인하는 올바른 방법은 [ "$#" -eq 0 ]입니다. ( $#인수의 개수입니다).


2

가끔 실수로 키보드를 만져 공백을 제거한 경우.

if [ "$myvar" = "something"]; then
    do something
fi

이 오류 메시지가 나타납니다. ']'앞의 공백이 필요합니다.


1
다음과 같은 다른 구문 오류가 발생한다고 생각합니다. line 21 : [:
Joe Holloway

1

스크립트와 동일한 문제가있었습니다. 그러나 내가 약간의 수정을했을 때 그것은 나를 위해 일했다. 나는 이것을 좋아했다 :-

export k=$(date "+%k");
if [ $k -ge 16 ] 
    then exit 0; 
else 
    echo "good job for nothing"; 
fi;

그런 식으로 문제를 해결했습니다. 그것이 당신에게도 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.