Makefile 하위 쉘의 Bash 변수 대체

Makefile 하위 쉘의 Bash 변수 대체

/tmp/file내 Makefile은 다음을 사용하여 도커 컨테이너 내에 파일을 생성 해야 하며 실제로 생성합니다 make test.

test:   
    (cd subdirectory && docker-compose exec webserver bash -c "\
        MYTEXT=hello && \
        echo 'this is $$MYTEXT world' > /tmp/file && \
        cat /tmp/file
    ")

그러나 이는 예상대로 작동하지 않았습니다. /tmp/file내용이 있습니다:

this is  world

하지만 그랬으면 좋겠어

this is hello world

MYTEXT를 다음 명령( echo)에 전달하는 방법은 무엇입니까?

답변1

make코드를 해석하기 위해 sh(기본적으로 변수를 변경하지 않는 한 ) 호출됩니다 ( 각 줄의 끝에서 사용 하지 않는 한 한 줄에 한 번씩 ).SHELL makesh\

여기서는 코드에 포함하고 싶지만 확장되지 않고 코드에 전달되기를 원하므로 $$MYTEXT$MYTEXT따옴표 가 확장 되는 것을 방지하려면 내부에 큰따옴표를 사용하거나 작은따옴표를 사용해야 합니다 . 어쨌든, 당신은 그것을 확장 하고 싶기 때문에 코드에 작은따옴표를 사용하고 싶지 않습니다 .sh$MYTEXTshbash\bash$MYTEXT$MYTEXTbash

그래서:

test:   
    (cd subdirectory && \
      docker-compose exec webserver bash -c '\
        MYTEXT=hello && \
        echo "this is $$MYTEXT world" > /tmp/file && \
        cat /tmp/file \
      '\
    )

을 실행하면 strace -s999 -fe execve make다음과 같은 내용이 표시됩니다( 여기서 docker-compose exec webserver bash대체됨 bash).

[pid 22370] execve("/bin/sh", ["/bin/sh", "-c", "(cd subdirectory && \\\n  exec bash -c '\\\n    MYTEXT=hello && \\\n    echo \"this is $MYTEXT world\" > /tmp/file && \\\n    cat /tmp/file \\\n  '\\\n)"], 0x555ce503e620 /* 52 vars */) = 0
strace: Process 22371 attached
[pid 22371] execve("/bin/bash", ["bash", "-c", "\\\n    MYTEXT=hello && \\\n    echo \"this is $MYTEXT world\" > /tmp/file && \\\n    cat /tmp/file \\\n  "], 0x563430f3e8f8 /* 52 vars */) = 0
[pid 22371] execve("/bin/cat", ["cat", "/tmp/file"], 0x55e9509edc10 /* 52 vars */) = 0
this is hello world

서브셸은 호출을 실행하는 한 프로세스의 작업 디렉터리만 변경 하고 나중에 다른 명령을 실행하여 실행되는 다른 셸의 작업 디렉터리에는 영향을 주지 않으므로 (...)여기서는 필요하지 않습니다 .cdshmake

답변2

스크립트를 가져와서 make 외부에서 실행하세요.

  • 실행해shellcheck
  • 시험을 받다

따옴표에 뭔가 문제가 있다는 것을 알게 될 것입니다.

관련 정보