GNU Makefile에서 프로세스 대체


11

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)'

이것이 의미하는 바는 무엇이며 임시 파일을 사용하지 않고 두 개의 출력을 여전히 다른 방법으로 사용할 수 있습니까?

답변:


20

/bin/sh수 있습니다 bash시스템에 있지만, 같은 호출 할 때 sh, bash(것처럼 POSIX 모드에서 실행됩니다 POSIXLY_CORRECT정의, 또는이 시작되었다 --posix).

이 모드에서는 프로세스 대체가 없습니다.

솔루션 :

all:
    command1 >file1
    command2 >file2
    diff file1 file2
    rm -f file1 file2

대안 :

all:
    bash -c "diff <(command1) <(command2)"

또는 Makefile 변수 SHELL/bin/bash다음 과 같이 정의하십시오 .

SHELL=/bin/bash

이식성을 원한다면 첫 번째 해결책으로 가십시오. 에 대한 종속성이 있으면 bash두 번째를 선택하십시오. 비 GNU make구현 에 대해 추가로 신경 쓸 필요가 없다면 세 번째를 사용하십시오.


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

유틸리티대한 이론적 근거make 는 다음을 사용하는 것입니다 bash -c.

역사적 MAKESHELL특징 및 다른 make구현 에 의해 제공된 관련 특징 은 생략되었다. 일부 구현에서는 사용자가 make명령 을 실행하는 데 사용되는 셸을 무시하도록하는 데 사용됩니다 . 이것은 혼란 스러웠다. 휴대용의 make경우, 쉘은 makefile 작성기에서 선택해야합니다. 또한, makefile 작성기는 대체 쉘을 사용할 것을 요구할 수 없으며 makefile을 이식 가능한 것으로 간주합니다. 대체 쉘을 지정하기위한 메커니즘을 표준화 할 수는 있지만 기존 구현에서는 이러한 메커니즘에 동의하지 않으며 makefile 작성자는 대상 규칙에 쉘 이름을 지정하여 대체 쉘을 이미 호출 할 수 있습니다. 예를 들면 다음과 같습니다.

python -c "foo"


bash임시 파일을 사용하지 않고 Makefile 또는 diff 문제에 대한 다른 솔루션 을 호출하는 방법이 있습니까?
Johannes

두 개의 임시 파일을 사용하십시오. 어쨌든 프로세스 대체 방법이 수행하는 방식과 거의 같습니다.
Kusalananda

3
당신은 또한 설정할 수 SHELL/bin/bash메이크있다.
Stephen Kitt

1
@Johannes Kusalananda의 답변에 정보가 추가되었습니다.이 정보는 다양한 옵션과 사용 가능한 환경을 제공하기 때문에 훌륭합니다. 차라리 당신은 ...이 답변을 받아 들일 것 (그러나 나는 감정을 주셔서 감사합니다!)
스티븐 키트를

2
SHELL 변수를 사용하는 것이 POSIX 호환이 아니라는 정보는 매우 도움이되었습니다. 어쩌면 여전히을 사용하는 것이 좋습니다 bash -c.
Johannes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.