변수를 사용하지 않고 직접 사용하면 조건이 작동하지 않는 이유는 무엇입니까?

변수를 사용하지 않고 직접 사용하면 조건이 작동하지 않는 이유는 무엇입니까?

매개변수가 너무 많다는 오류가 발생합니다.

if [ $( file -b $i ) == "directory" ]

그런데 이걸 시도해보니

name=$( file -b $i )
if [ name == "directory" ]

아주 잘 작동하는 것 같습니다.

누군가 이것을 설명하거나 문서에서 설명을 지적할 수 있습니까?

답변1

몇 가지 질문이 있습니다:

  • ][는 () 매개변수의 끝을 나타내며 test, 이는 여러 개의 s가 있는 마지막 매개변수여야 합니다. ]이는 아마도 잘못된 것입니다.

    if [ $( file -b $i ) == "directory" ]
    
  • 위의 방법을 사용하면 변수 확장( ) 및 명령 대체 ( command ) bash: [: too many arguments의 출력에서 ​​단어 분할이 수행되고 그 앞에 여러 단어가 표시되어 오류 메시지가 발생하기 때문에 이러한 오류가 발생합니다. 변수 확장 및 명령 대체를 인용해야 합니다.$i$()file[=

    [ "$(file -b "$1")" == "directory" ]
    

참고로, 전자가 단어 분할(및 경로 이름 확장)을 처리하므로 대신 bash키워드를 사용해야 합니다.[[[

답변2

if [ $( file -b $i ) == "directory" ]

여기에는 두 가지 질문이 있습니다.

  • =문자열 비교에는 Single을 사용하십시오 . 올바른 구문을 확인하세요 man test(대부분의 경우 쉘 특정 구현이 있으므로 문서가 없으면 [쉘 구문을 참조하세요). 꼭 필요한 경우 이를 사용하십시오. 이는 bash, ksh, zsh를 포함한 많은 Bourne 쉘의 기능입니다. 참고: bash에 존재하는 동안man pagetest==[[==버전 2.0부터, "=는 POSIX 적합성을 위한 테스트 명령과 함께 사용해야 합니다." (배쉬 매뉴얼 페이지).

  • 모든 변수를 "$()"특히 관심 있는 항목 으로 참조하세요 $i. $i쉘의 단어 확장으로 인해 공백이 있는 파일 이름은 여러 단어로 분할됩니다.

예:

bash-4.3$ mkdir with\ space
bash-4.3$ i="./with space"
bash-4.3$ set -x
bash-4.3$ [ $( file -b $i ) == "directory" ] && echo "YES"
++ file -b ./with space
+ '[' cannot open '`./with'\''' '(No' such file or 'directory)' cannot open '`space'\''' '(No' such file or 'directory)' == directory ']'
bash: [: too many arguments

name=$( file -b $i )
if [ name == "directory" ]

여기에 질문:

  • name변수에 대한 확장은 없습니다. 여기에는 문자열 "이름"만 있습니다. 넌 "$name"다시 싱글이 되어야 해=

test또한 종료 상태가 false(종료 상태 1)를 반환 하므로 작동할 수 없습니다.

$ name=$(file -b /etc)
$ set -x
$ [ name == "directory" ]
+ '[' name '==' directory ']'
$ echo $?
+ echo 1
1

위의 내용은 bash쉘 에서 mksh테스트되었습니다 .

답변3

질문이 많습니다! "작동하는" 부분을 살펴보겠습니다.

 name=$( file -b $i )
 if [ name == "directory" ]

이는 파일 명령의 출력을 명명된 변수에 할당 name하지만 이를 사용하지 않고 대신 , 및 [3개의 인수를 사용하여 명령을 실행합니다 . Accept 는 bash 확장입니다.name==directory==

대신 사용하도록 수정하면 $name많은 경우 name문제가 다시 발생하게 됩니다. 이는 여러 단어 결과가 반환되기 too many arguments때문입니다 . 예를 들어 명령을 실행한 후에는 .fileASCII text

if [ ASCII text == directory ]

이제 명령에 일부 그룹화가 누락된 것이 분명해졌습니다.

if [ "$(file -b -- "$i")" = "directory" ]

아마도 당신이 원하는 것: =대신 ==이식성을 위해 명령 대체 결과를 인용하십시오.당신이 거의 항상 하고 싶은 일.

관련 정보