Makefile 대상에서 Bash 구문을 사용하려면 어떻게해야합니까?


208

나는 종종 Bash 구문이 매우 유용 하다는 것을 알게 된다 diff <(sort file1) <(sort file2).

이러한 Bash 명령을 Makefile에서 사용할 수 있습니까? 나는 이와 같은 것을 생각하고있다 :

file-differences:
    diff <(sort file1) <(sort file2) > $@

내 GNU Make 3.80 에서는 명령을 실행하는 shell대신 대신 사용하기 때문에 오류가 발생 bash합니다.


이것은 정확히 내 문제였습니다.이 질문을 찾기 위해 적어도 한 시간이 걸렸습니다! 미래 독자들이 찾을 수 있도록 여기에 오류 메시지를 남깁니다. /bin/sh: -c: line 0: syntax error near unexpected token ( '`
David

답변:


380

GNU Make 문서에서

5.3.1 Choosing the Shell
------------------------

The program used as the shell is taken from the variable `SHELL'.  If
this variable is not set in your makefile, the program `/bin/sh' is
used as the shell.

따라서 SHELL := /bin/bashmakefile의 맨 위에 놓으 십시오.

BTW : 적어도 GNU Make의 경우 하나의 대상에 대해이 작업을 수행 할 수도 있습니다. 각 대상은 다음과 같이 고유 한 변수 할당을 가질 수 있습니다.

all: a b

a:
    @echo "a is $$0"

b: SHELL:=/bin/bash   # HERE: this is setting the shell for b only
b:
    @echo "b is $$0"

인쇄됩니다 :

a is /bin/sh
b is /bin/bash

자세한 내용은 설명서의 "대상별 변수 값"을 참조하십시오. 그 줄은 Makefile의 어느 곳으로나 갈 수 있으며, 대상 바로 앞에있을 필요는 없습니다.


43
에서을 (를) 기다리는 500 현상금 man. 타이밍에 대해 이야기하십시오. : P
SiddharthaRT

3
@inLoveWithPython 글쎄, info실제로, 그것이 실제로 Andy에게 도움이 된 것 같습니다. 나는 그런 날을 보냈다는 것을 알고있다.
derobert

3
의심스러운 경우 @derobert는 문자 그대로 SHELL=/bin/bashMakefile의 첫 번째 줄 (또는 주석 바로 다음)을 의미했습니다.
Yauhen Yakimovich


2
하나의 특정 대상 만 SHELL 변수를 변경할 수 있지만 다른 대상은 그대로 두는 것이 가능합니까?
antred

18

깃발을 bash사용하여 직접 전화 할 수 있습니다 -c.

bash -c "diff <(sort file1) <(sort file2) > $@"

물론 변수 $ @로 리디렉션 할 수는 없지만이 작업을 시도 할 때 -bash: $@: ambiguous redirect오류 메시지가 표시되어 너무 많이 들어가기 전에 살펴보고 싶을 수도 있습니다 ( bash 3.2.something을 사용하면 다르게 작동합니다).


4

이식성이 중요한 경우 Makefile의 특정 쉘에 의존하지 않을 수 있습니다. 모든 환경에서 bash를 사용할 수있는 것은 아닙니다.


4

기본 쉘을 사용하는 대신 Makefile 내에서 bash를 직접 호출 할 수 있습니다.

bash -c "ls -al"

대신에:

ls -al

1
참고 make환경 변수 SHELL의 값을 무시합니다.
choroba

2

SHELL 변수를 bash를 가리 키도록 명시 적으로 설정하지 않고이 작업을 수행 할 수 있습니다. SHELL이 후속 메이크 파일에 의해 상속되지 않거나 환경에서 가져 오기 때문에 메이크 파일이 많은 경우에 유용 할 수 있습니다. 또한 코드를 컴파일하는 사람이 자신의 시스템을 이러한 방식으로 구성해야합니다.

sudo dpkg-reconfigure dash프롬프트에서 'no'를 실행 하고 응답 하면 시스템은 대시를 기본 쉘로 사용하지 않습니다. 그런 다음 bash를 가리 킵니다 (적어도 우분투에서는). 시스템 쉘로 dash를 사용하는 것이 조금 더 효율적입니다.


1
이름으로 호출되면 shbash는 호환 모드 ( set -o posix) 에서 실행됩니다 . OP가 사용하려고하는 기능인 프로세스 대체는이 모드에서 사용할 수 없습니다.
찰스 더피

1

작동하는 한 가지 방법은 대상의 첫 번째 줄에 이런 식으로 배치하는 것입니다.

your-target: $(eval SHELL:=/bin/bash)
    @echo "here shell is $$0"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.