함수에 인수를 있는 그대로 전달합니다.

함수에 인수를 있는 그대로 전달합니다.

본 기사:함수에 인수를 있는 그대로 정확하게 전달합니다.

그러나 설정이 약간 다릅니다.

나는 3개의 bash 기능인 foo, bar, baz를 가지고 있습니다. 해당 설정은 다음과 같습니다.

foo() {
  bar $1
}

bar() {
  var1=$1
  var2=$2
  echo "$var1" test "$var2"
}
export ENV_VAR_1="1"
export ENV_VAR_2="2 3"

foo "${ENV_VAR_1} ${ENV_VAR_2}"

내 예상 결과는 다음과 같습니다

1 test 2 3

그러나 출력은 다음과 같습니다.

1 test 2

나는 이것이 왜 그런지 이해합니다. bar는 다음과 같이 실행됩니다.

bar 1 2 3

내 질문은 : 그것을 실행하는 방법입니다

bar 1 "2 3"

내가 시도한 것:

foo () {bar "$1"} 
# Out: 1 2 3 test. Makes sense since "1 2 3" is interpreted as a single argument.

답변1

이는 문자열을 인수로 제공합니다 foo.

foo "${ENV_VAR_1} ${ENV_VAR_2}"

$1따옴표 안에 있지 않기 때문에 쉘은 단어 분리를 수행하므로 다음과 같은 세 가지 인수가 제공됩니다 bar.

bar $1

S1토큰화는 이러한 문자의 원래 출처에 관계없이 수행됩니다 .

더 간단한 예

이를 다음과 같이 정의해보자 x:

$ x="${ENV_VAR_1} ${ENV_VAR_2}"

이제 인쇄해 봅시다 "$x":

$ printf "%s\n" "$x"
1 2 3

보시다시피 "$x"매개변수로 해석됩니다. 이와 대조적으로 다음을 고려하십시오.

$ printf "%s\n" $x
1
2
3

위에서는 $x세 개의 매개변수를 생성할 때 토큰화가 수행됩니다.

쉘 문자열에는 기록 개념이 없습니다. 문자열은 할당되기 전에 문자열의 일부라는 기록 x이 없습니다 . 문자열은 , 공백, , 공백 으로만 구성되며 단어 분할은 공백에서 작동합니다.2 3xx123

대안: 자신만의 IFS를 선택하세요

그러면 원하는 출력이 생성됩니다.

$ foo() ( IFS=@;  bar $1; )
$ foo "${ENV_VAR_1}@${ENV_VAR_2}"
1 test 2 3

에서는 로 foo설정했습니다 . 따라서 이후의 모든 단어 분할은 단어 구분 기호를 사용하여 수행됩니다. 따라서 를 호출할 때 단어 분할이 필요한 곳에 를 배치합니다 .IFS@@foo@

답변2

foo5자 문자열인 하나의 인수를 함수에 전달합니다 1 2 3. 세 숫자를 공백으로 구분하세요. foo이러한 공간을 다르게 취급할 이유가 없습니다.

개별 문자열을 조합 ${ENV_VAR_1}하거나 ${ENV_VAR_2}내부에서 사용하면 정보가 손실됩니다. 손실된 정보를 복구하려면 마법이 필요하지만 컴퓨터는 그렇게 할 수 없습니다. 1 2와 사이의 분리를 유지하려면 호출 방식을 3변경해야 합니다 . foo두 개의 별도 매개변수를 전달합니다.

foo "${ENV_VAR_1}" "${ENV_VAR_2}"

그렇다면 당신이 해야 할 일은참조 수정통화 bar. 두 개의 매개변수를 전달하십시오.

foo () {
  bar "$1" "$2"
}

또는 전체 인수 목록을 전달합니다.

foo () {
  bar "$@"
}

관련 정보