왜 오류가 발생하는지 알 수 없습니다. 실제 코드를 시뮬레이션한 테스트 코드입니다. 래퍼를 작성 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"
작동합니다.