GNU Makefile의 프로세스 대체

GNU Makefile의 프로세스 대체

Bash 프롬프트에서 의사 파일을 사용하여 diff를 실행할 수 있습니다:

diff <(echo test) <(echo test)

이것을 그대로 Makefile에 추가하면 실패합니다.

all:
        diff <(echo test) <(echo test)

오류(힌트: /bin/sh는 이 시스템의 /bin/bash를 가리킵니다):

/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'

이것이 의미하는 바는 무엇이며, 임시 파일을 사용하지 않고 두 출력을 비교하는 방법이 있습니까?

답변1

/bin/shbash시스템에 있을 수 있지만 sh로 호출되면 bashPOSIX 모드에서 실행됩니다(마치 POSIXLY_CORRECT정의되었거나 로 시작된 것처럼 --posix).

이 모드에서는 프로세스 대체가 존재하지 않습니다.

솔루션:

  1. 명시적 임시 파일을 사용하십시오.

    all:
        command1 >tmpfile
        command2 | diff tmpfile -
        rm -f tmpfile
    
  2. bash -c인라인 스크립트를 사용하십시오 .

    all:
        bash -c 'diff <(command1) <(command2)'
    
  3. Makefile 변수를 SHELL다음과 같이 정의하십시오(또는 시스템에 있는 /bin/bash경로 ).bash

    SHELL=/bin/bash
    

이식성을 원한다면 첫 번째 솔루션을 선택하세요. 에 대한 종속성이 괜찮다면 bash두 번째를 선택하십시오. GNU가 아닌 구현에 대해 추가로 신경 쓸 필요가 없다면 make세 번째를 사용하십시오.


설정 관련 SHELL: POSIX 표준에서는 Makefile의 실행 파일 이 system(). make이 함수는 환경 변수를 사용한다고 보장하지 않습니다 SHELL(사실 표준에서는 사용을 권장하지 않습니다). 표준은 또한 Makefile 변수 설정이 SHELL파일에 영향을 미치지 않아야 한다고 말합니다.환경 변수 SHELL. make그러나 내가 아는 대부분의 구현에서는 Makefile 변수가 SHELL명령을 실행하는 데 사용됩니다.

의 제안make유틸리티 의 이론적 근거사용하는 것입니다 bash -c:

다른 구현에서 제공되는 역사적 MAKESHELL기능 및 관련 기능은 make생략되었습니다. 일부 구현에서는 사용자가 명령을 실행하는 데 사용되는 셸을 재정의할 수 있도록 하는 데 사용됩니다 make. 이것은 혼란스러웠습니다. 이식 가능한 경우 makemakefile 작성자가 쉘을 선택해야 합니다. 또한 메이크파일 작성자는 대체 쉘을 사용하도록 요구할 수 없으며 여전히 메이크파일의 이식성을 고려합니다. 대체 쉘을 지정하는 메커니즘을 표준화하는 것이 가능하지만 기존 구현은 이러한 메커니즘에 동의하지 않으며 makefile 작성자는 대상에 대한 규칙에 쉘 이름을 지정하여 이미 대체 쉘을 호출할 수 있습니다. 예를 들어:

python -c "foo"

관련 정보