변수 확장은 변수가 있는 컨텍스트에 따라 다르게 작동합니까?

변수 확장은 변수가 있는 컨텍스트에 따라 다르게 작동합니까?

내가 다음을 수행한다고 가정해 보겠습니다.

IFS=,
x="hello,hi,world"
y=$x

ystring 이 있으므로 다음과 같이 대체됩니다 hello hi world.y=$x

y="hello hi world"

이제 다음 스크립트가 있다고 가정해 보겠습니다.

IFS=,
x="hello,hi,world"
if [ $x = "hello hi world" ]
then
    echo "equal"
fi

위 스크립트를 실행할 때 다음 오류가 발생합니다.

test.sh: line 3: [: too many arguments

나는 명령문이 실행될 때 대체되는 대신 대체되기 if [ $x = "hello hi world" ]때문에 이 오류가 발생한다고 가정합니다.if [ hello hi world = "hello hi world" ]if [ "hello hi world" = "hello hi world" ]

따라서 이는 변수가 $x해당 컨텍스트에 따라 두 가지 다른 방식(큰따옴표가 있는 경우와 큰따옴표가 없는 경우)으로 확장된다는 의미입니다.

내가 맞나요?

답변1

y끈이 있을 거예요hello hi world

아니 난 할 수 없어. 변수 할당의 확장은 단어 분할이나 파일 이름 글로빙의 영향을 받지 않습니다. (어떤 의미에서는 항상 큰따옴표로 묶인 것처럼 동작합니다.) 다음을 참조하세요.언제 큰따옴표가 필요합니까?

$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world

if [ $x = "hello hi world" ]명령문이 다음으로 대체되었기 때문에 이 오류가 발생한다고 가정합니다.if [ hello hi world = "hello hi world" ]

네, 그렇죠. 텍스트 기반 대체는 아니지만 $x여기에서 참조되지 않았기 때문에 토큰화를 거치며 명령은 예상한 4개 대신 [6개의 다른 인수( hello, hi, world, =및 ) hello hi world를 확인합니다.]

답변2

할당에 변수를 사용하면 참조와 관련하여 다르게 동작합니다. 존재하다

y=$x

분사를 수행하지 않습니다. 즉, 다음과 같습니다.

y="$x"

그러나 일반적인 매개변수 확장에서는 다음과 같습니다.

if [ $x =

따옴표가 있든 없든 차이가 있습니다. 참고: 따옴표를 사용하면 $x확장되지 "hello hi world"않지만 "hello,hi,world".

답변3

변수 할당 중에는 토큰화가 발생하지 y않으므로 hello,hi,world. 그러나 단어 분리는 내부적으로 발생하며 [], 설정한 이후에는 별도의 단어 IFS=,로 확장됩니다 .hello hi world

문제는 [특정 개수의 인수가 필요하다는 점인데, 토큰화로 인해 너무 많은 인수를 받았다고 알려줍니다. 태그를 지정했으므로 bash고급 명령을 사용하여 [[ ]]단어 분리를 비활성화하면 오류가 발생하지 않습니다.

실제로 쌍을 토큰화하려면 x다음을 수행하면 됩니다 y="$(IFS=','; echo $x)". 이것은 hello hi world에 단어로 할당됩니다 y.

답변4

인용 문제가 있습니다:

  1. 변수 확장:

    y는 hello hi world라는 문자열을 받게 됩니다.

    아니요, 그렇지 않습니다. 하지만 메아리가 있어인용되지 않음다음과 같은 값을 인쇄합니다.

    $ IFS=,
    $ x="hello,hi,world"
    $ y=$x
    $ echo $y
    hello hi world
    

    예, IFS 문자( ,)는 변수 확장을 구분하고 echo는 인수 사이에 공백을 넣습니다. 자세히 확인하세요.

    $ printf '<%s>\n' $y
    <hello>
    <hi>
    <world>
    

    그러나 참조된 확장은 IFS 또는 분할에 의해 변경되지 않습니다.

    $ echo "$y"
    hello,hi,world
    $ printf '<%s>\n' "$y"
    <hello,hi,world>
    
  2. 테스트 라인

    [ $x = "hello hi world" ]
    

    여기서도 동일한 참조 문제가 발생하며 변수가 확장됩니다.그리고말로. 라인은 다음과 같습니다:

    [ hello hi world = "hello hi world" ]
    

    세 개의 매개변수 "hello", "hi" 및 "world"는 올바른 테스트 구조로 구문 분석될 수 없습니다.

    그러나 이는 다음을 수행합니다.

    $ y=hello,=,world,-o,hello
    $ [ $y = "hello" ] && echo yes || echo no
    yes
    

    실행되는 내용은 다음과 같습니다.

    [ hello = world -o hello = "hello" ] && echo yes || echo no
    

    인용하면 분할을 피할 수 있습니다.

    $ y=hello,hi,world
    $ [ "$y" = "hello,hi,world" ] && echo yes || echo no
    yes
    

    다음 구성을 사용하면 [[분할을 피할 수도 있습니다 .

    $ y=hello,hi,world
    $ [[ $y == "hello,hi,world" ]] && echo yes || echo no
    yes
    
  3. 너의 문제:

    내가 맞나요?

    아니요, 변수는 매번 같은 방식으로 확장됩니다.

긴 이야기 짧게

확장 기능을 인용해 보세요.

관련 정보