$@를 명령에 전달하고 따옴표를 유지하세요.

$@를 명령에 전달하고 따옴표를 유지하세요.

나는 git동작을 수정하기 위해 설명된 방법을 사용 하려고 합니다.여기, 하지만 원래 입력의 따옴표를 잃지 않고 콘텐츠를 올바르게 전달하는 방법에 $@어려움을 겪고 있습니다 .

기본적으로 나는 이것을 가지고 있습니다 :

# foo.sh

#!/bin/bash
cmd=$1
shift
args=$@
if [ $cmd == "bar" ]; then args=('--baz' "${args[@]}"); fi
echo git $cmd ${args[@]}

하지만 실행하면 필요한 것이 아니라 ./foo.sh bar -a "one two three"출력(따라서 실행)됩니다 ../foo.sh bar --baz -a one two./foo.sh bar --baz -a "one two"

$@다른 명령에 올바르게 전달하고 인용된 인수를 유지하는 방법을 모르겠습니다 . 가능합니까? 어떻게?

답변1

사용할 때 배열이라고 "${args[@]}"가정 하지만 그렇지 않습니다.args

배열이 되려면 args배열 할당을 사용하여 값을 할당해야 합니다.

args=( "$@" )

확장할 때 배열의 요소를 개별적으로 인용하려면 ${args[@]}확장과 마찬가지로 큰따옴표를 사용해야 합니다 "$@".

echo git "$cmd" "${args[@]}"

이 간단한 예에서는 args별도의 배열이 전혀 필요하지 않습니다.

#!/bin/sh

cmd=$1
shift

if [ "$cmd" = "bar" ]; then
   set -- --baz "$@"
fi

echo git "$cmd" "$@"

위 명령은 따옴표를 출력하지 않습니다 echo. 하지만 echo정확히 두 개의 인수( gitand) 를 가져오고 $cmd이 시점에는 많은 내용이 있으므로 안심하셔도 됩니다 . $@이는 쉘이 명령을 실행하기 전에 명령에서 따옴표를 제거하기 때문입니다. 예를 들어 echo "one two" three출력 과 비교할 수 있습니다 .

육안 검사를 위해 명령을 출력하는 더 좋은 방법은 다음과 같습니다.

printf 'Arg: %s\n' git "$cmd" "$@"

그러면 각 개별 인수가 printf한 줄에 인쇄됩니다(문자열 접두사가 붙음 Arg:).

명령 (또는 별도의 배열을 사용하는 경우) git은 올바르게 실행됩니다(변수가 의미가 있다고 가정(예: 옵션이 있는 하위 명령이 없는 일반 명령 )).git "$cmd" "$@"git "$cmd" "${args[@]}"gitbar--baz

관련된:

관련 정보