我经常发现 Bash 语法非常有用,例如 diff <(sort file1) <(sort file2)
中的进程替换。
是否可以在 Makefile 中使用此类 Bash 命令?我在想这样的事情:
file-differences:
diff <(sort file1) <(sort file2) > $@
在我的 GNU Make 3.80 中,这将给出一个错误,因为它使用 shell
而不是 bash
来执行命令。
/bin/sh: -c: line 0: syntax error near unexpected token
('`
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 的顶部,你应该很高兴。
顺便说一句:您也可以为一个目标执行此操作,至少对于 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 中的任何位置,它不必紧挨在目标之前。
您可以直接调用 bash
,使用 -c
标志:
bash -c "diff <(sort file1) <(sort file2) > $@"
当然,您可能无法重定向到变量 $@,但是当我尝试执行此操作时,我收到 -bash: $@: ambiguous redirect
作为错误消息,因此您可能需要在深入了解之前先调查一下(尽管我正在使用 bash 3.2.something,所以也许你的工作方式不同)。
一种可行的方法是将它放在目标的第一行:
your-target: $(eval SHELL:=/bin/bash)
@echo "here shell is $$0"
如果可移植性很重要,您可能不想依赖 Makefile 中的特定外壳。并非所有环境都有 bash 可用。
您可以直接在 Makefile 中调用 bash 而不是使用默认 shell:
bash -c "ls -al"
代替:
ls -al
make
忽略环境变量 SHELL 的值。
有一种方法可以做到这一点,而无需将您的 SHELL 变量显式设置为指向 bash。如果您有许多 makefile,这会很有用,因为 SHELL 不会被后续的 makefile 继承或取自环境。您还需要确保编译您的代码的任何人都以这种方式配置他们的系统。
如果您运行 sudo dpkg-reconfigure dash
并对提示回答“否”,您的系统将不会使用破折号作为默认 shell。然后它将指向 bash(至少在 Ubuntu 中)。请注意,使用破折号作为系统外壳会更有效。
sh
调用时,bash 以兼容模式 (set -o posix
) 运行。 OP 尝试使用的功能(进程替换)在此模式下不可用。
这不是问题的直接答案,makeit 是有限的 Makefile 替换为 bash 语法,在某些情况下它可能很有用(我是作者)
规则可以定义为 bash 函数
自动完成功能
基本思想是在脚本末尾有 while
循环:
while [ $# != 0 ]; do
if [ "$(type -t $1)" == 'function' ]; then
$1
else
exit 1
fi
shift
done
https://asciinema.org/a/435159
https://asciinema.org/a/Nvx7QOvUyMnZc8MVfKk2xETnj.svg
man
的报价。谈论时间。 :Pinfo
,实际上,但是,我想它确实帮助了安迪。我知道我有过这样的日子...SHELL=/bin/bash
作为 Makefile 的第一行(或在评论之后)。/usr/bin/env bash
,它将使用 PATH 中的bash
。但是如果它只是SHELL := bash
呢?$(info $(SHELL))
并查看/bin/bash
可能会发生的一些混淆,还有一个注意事项:它没有任何意义! GNU Make 从环境中继承变量,因此SHELL
变量来自环境,但是当$(origin SHELL)
为environment
(我的猜测)时它不会使用它。