bash 스크립트 함수 매개변수 문제

bash 스크립트 함수 매개변수 문제

왜 오류가 발생하는지 알 수 없습니다. 실제 코드를 시뮬레이션한 테스트 코드입니다. 래퍼를 작성 find하고 모든 매개변수를 허용하고 싶기 때문에 각 매개변수를 작은따옴표로 묶었습니다.

#!/bin/bash

function find2 {

   ARGS="/usr/bin/find"
   while [[ $# -gt 0 ]]; do
      ARGS="$ARGS '$1'"
      shift
   done
   echo CALLING:  $ARGS
   $ARGS

}

find2 /tmp/test -name "hello.c"    # THIS IS THE DESIRED IMPLEMENTATION (doesn't work)

find '/tmp/test' '-name' 'hello.c'     # THIS IS FOR DEBUGGING (works)

"find2"가 작동하길 원하지만 작동하지 않습니다. 다음과 같은 결과가 나타납니다.

CALLING: /usr/bin/find '/tmp/test' '-name' 'hello.c'
/usr/bin/find: `\'/tmp/test\'': No such file or directory
/usr/bin/find: `\'-name\'': No such file or directory
/usr/bin/find: `\'hello.c\'': No such file or directory

그러나 (find2에 의해 생성된) 똑같은 명령을 직접 사용하면 제대로 작동합니다.

/tmp/test/hello.c

무슨 일이 일어났는지 모르겠어요.

답변1

(Bash에서) 값 배열로 변경할 수 있습니다.

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

그러나 이것은 작동하며 매우 간단합니다.

find2() {
    ARGS=( "/usr/bin/find" "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"
}

find2 /tmp/test -name "hello.c"

물론, 직접적인 방법도 가능합니다(함수가 있는 모든 쉘에서):

find2() {    /usr/bin/find "$@";   }

find2 /tmp/test -name "hello.c"

원본 코드가 실패하는 이유는 무엇입니까?

코드가 수행하는 작업을 "확인"하려면 set -x 또는 그 이상을 사용할 수 있습니다. 다음과 같이 echo를 printf로 바꾸십시오.

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

실행하면 다음과 같이 표시됩니다.

$ ./script.sh
<CALLING:> </usr/bin/find> </tmp/test> <-name> <hello.c> 

각 매개변수는 별도의 요소입니다(<> 위치에 유의하세요).

그러나 원본 코드(printf 추가)에서는 다음을 수행합니다.

function find2 {

    ARGS="/usr/bin/find"
    while [[ $# -gt 0 ]]; do
        ARGS="$ARGS '$1'"
        shift
    done
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    $ARGS

}   

find2 /tmp/test -name "hello.c"

실행되면 다음을 얻게 됩니다:

$ ./script.sh
<CALLING:> </usr/bin/find '/tmp/test' '-name' 'hello.c'>

모든 값은 개별 매개변수가 아닌 하나의 긴 텍스트 줄입니다(<> 배치에 유의하세요).

답변2

ARGS="$ARGS '$1'"줄을 (작은 따옴표 제거) 로 변경하면 ARGS="$ARGS $1"작동합니다.

관련 정보