2009-02-26 3 views
143

Я часто нахожу Bash синтаксис очень полезным, например. замещение процесса, как в diff <(sort file1) <(sort file2).Как использовать синтаксис Bash в целевых файлах Makefile?

Можно ли использовать такие команды Bash в Makefile? Я имею в виду что-то вроде этого:

file-differences: 
    diff <(sort file1) <(sort file2) > [email protected] 

В моем GNU Make 3.80 это даст ошибку, так как он использует shell вместо bash для выполнения команд.

ответ

258

Из документации 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/bash в верхней части Makefile, и вы должны быть хорошо идти.

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, она не должна быть непосредственно перед целью.

+21

500 бонусов, ожидающих цитаты из 'man'. Расскажите о таймингах. : P – SiddharthaRT

+3

@ inLoveWithPython Ну, 'info', на самом деле, но, я думаю, это действительно помогло Энди. Я знаю, что у меня были такие дни ... – derobert

+2

Если у вас есть сомнения, @derobert означал буквально: 'SHELL =/bin/bash' как первая строка Makefile (или сразу после комментария). –

10

Вы можете позвонить bash напрямую, используйте -c флаг:

bash -c "diff <(sort file1) <(sort file2) > [email protected]" 

Конечно, вы не можете быть в состоянии перенаправить к переменным $ @, но когда я попытался сделать это, я получил -bash: [email protected]: ambiguous redirect, как сообщение об ошибке, поэтому вы можете захотеть взглянуть на это, прежде чем вы тоже перейдете к этому (хотя я использую bash 3.2.something, поэтому, возможно, ваш работает по-другому).

2

Вы можете позвонить Баш непосредственно в вашем Makefile вместо оболочки по умолчанию:

bash -c "ls -al" 

вместо:

ls -al 
+0

Обратите внимание, что 'make' игнорирует значение переменной среды SHELL. – choroba

4

Если портативность важно, чтобы вы не можете зависеть от конкретной оболочки в вашем Makefile. Не все среды имеют доступ к bash.

1

Существует способ сделать это без явной настройки переменной SHELL, чтобы указать на bash. Это может быть полезно, если у вас есть много make-файлов, поскольку SHELL не наследуется последующими make-файлами или не берется из среды. Вы также должны быть уверены, что любой, кто компилирует ваш код, настраивает свою систему таким образом.

Если вы запустите sudo dpkg-reconfigure dash и ответьте «нет» на приглашение, ваша система не будет использовать тире в качестве оболочки по умолчанию. Затем он укажет на bash (по крайней мере, в Ubuntu). Обратите внимание, что использование тире в качестве вашей системной оболочки немного более эффективно.

+1

При вызове под именем 'sh' bash запускается в режиме совместимости (' set -o posix'). Функциональность, которую ОП пытается использовать, замена процесса недоступна в этом режиме. –

Смежные вопросы