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().c 라이브러리 함수에 의해 호출되어야 한다고 규정합니다 make. 이 함수는 환경 변수의 사용을 보장하지 않습니다 SHELL(사실 표준에서는 이를 권장하지 않습니다). 또한 표준에서는 Makefile 변수 설정이 SHELL영향을 미치지 않아야 함 을 자세히 설명합니다.환경 변수 SHELL. 그러나 내가 아는 대부분의 구현에서는 makeMakefile 변수가 SHELL명령을 실행하는 데 사용됩니다.

에 대한 제안make이 유틸리티의 기본 원리사용하는 것입니다 bash -c:

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

python -c "foo"

관련 정보