以下命令集在linux提示符下工作。
%cd ${ADIR}/exe; shopt -s extglob; rm -rf !(BDIR)但它在Makefile中不起作用
Linux命令- works
%cd ${ADIR}/exe; shopt -s extglob; rm -rf !(BDIR)Makefile中的命令
@cd ${ADIR}/exe; shopt -s extglob; rm -rf !\(BDIR\)生成文件消息
rm: cannot remove `!(BDIR)': No such file or directory发布于 2019-06-08 22:01:25
不幸的是,bash有一个奇怪的行为,那就是店铺设置直到换行符才会生效,所以同一行上的任何globbing都无法识别它。在shell提示符下尝试执行以下操作:
$ shopt -s extglob; echo !(BDIR)
bash: !: event not found然后分两行进行尝试:
$ shopt -s extglob
$ echo !(BDIR)
...works不幸的是,这意味着它几乎不可能与make一起使用。
您应该使用triplee's comment中建议的POSIX兼容版本,并且完全避免需要特殊的shell。
哦,看起来答案被删除了。无论如何,做一些类似这样的事情:
foo:
cd ${ADIR}/exe && for f in *; do \
case $$f in (BDIR) : ok ;; (*) rm -rf "$$f" ;; esac; \
done发布于 2019-06-08 21:17:57
您的Makefile的问题是,它避开了(和),这使得shell逐字解释它们。
第二个问题,
/bin/sh: -c: line 0: syntax error near unexpected token `('是由make使用sh而不是bash执行命令引起的。
!(...)通配符语法(和extglob)仅受bash支持,不受sh支持。
您可以显式调用bash:
@bash -c 'cd ${ADIR}/exe; shopt -s extglob; rm -rf !(BDIR)'但这也不起作用,因为在读取下一行输入之前,extglob不会生效,因此!( )仍然会抛出语法错误。
我们需要一种使用单个shell调用来运行多行命令的方法。不幸的是,make使这变得不必要地复杂。
一种可能的解决方案是:
SHELL = /bin/bash
...
@bash -c $$'cd ${ADIR}/exe; shopt -s extglob\nrm -rf !(BDIR)'这将告诉make使用bash来执行所有配方(而不是/bin/sh)。然后,我们再次手动运行bash,但使用$'...'将命令字符串引起来。这让我们可以编写\n来嵌入一个文字换行符,从而使extglob / !( ... )工作。
我们需要两个$$来转义make的$,所以$'...'变成了$$'...'。
我对这个解决方案不太满意。
https://stackoverflow.com/questions/56504226
复制相似问题