我经常发现Bash语法非常有用,例如,像diff <(sort file1) <(sort file2)这样的进程替换。
是否可以在Makefile中使用这样的Bash命令?我的想法是这样的:
file-differences:
diff <(sort file1) <(sort file2) > $@
在我的GNU Make 3.80中,这将给出一个错误,因为它使用shell而不是bash来执行命令。
我经常发现Bash语法非常有用,例如,像diff <(sort file1) <(sort file2)这样的进程替换。
是否可以在Makefile中使用这样的Bash命令?我的想法是这样的:
file-differences:
diff <(sort file1) <(sort file2) > $@
在我的GNU Make 3.80中,这将给出一个错误,因为它使用shell而不是bash来执行命令。
当前回答
还有一种方法是把它放在你的目标的第一行:
your-target: $(eval SHELL:=/bin/bash)
@echo "here shell is $$0"
其他回答
你可以直接在Makefile中调用bash,而不是使用默认shell:
bash -c "ls -al"
而不是:
ls -al
你可以直接调用bash,使用-c标志:
bash -c "diff <(sort file1) <(sort file2) > $@"
当然,您可能无法重定向到变量$@,但是当我尝试这样做时,我得到了-bash: $@:模棱两可的重定向作为错误消息,所以您可能希望在深入了解这个问题之前研究一下(尽管我使用的是bash 3.2。也许你的工作方式不同)。
如果可移植性很重要,您可能不希望依赖Makefile中的特定shell。并非所有环境都有bash可用。
在GNU Make文档中,
5.3.2 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中的任何地方,它不必紧挨着目标。
这不是对问题的直接回答,makeit是有限的Makefile替换bash语法,在某些情况下可能有用(我是作者)
规则可以定义为bash-function 自动完成功能
基本思想是在脚本的末尾使用while循环:
while [ $# != 0 ]; do
if [ "$(type -t $1)" == 'function' ]; then
$1
else
exit 1
fi
shift
done
https://asciinema.org/a/435159