본 기사:함수에 인수를 있는 그대로 정확하게 전달합니다.
그러나 설정이 약간 다릅니다.
나는 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 3
x
x
1
2
3
대안: 자신만의 IFS를 선택하세요
그러면 원하는 출력이 생성됩니다.
$ foo() ( IFS=@; bar $1; )
$ foo "${ENV_VAR_1}@${ENV_VAR_2}"
1 test 2 3
에서는 로 foo
설정했습니다 . 따라서 이후의 모든 단어 분할은 단어 구분 기호를 사용하여 수행됩니다. 따라서 를 호출할 때 단어 분할이 필요한 곳에 를 배치합니다 .IFS
@
@
foo
@
답변2
foo
5자 문자열인 하나의 인수를 함수에 전달합니다 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 "$@"
}