我有几个目录,其中有 Makefile。
我制作了这个脚本来运行这些 Makefile(如果存在):
find . -name "Makefile" -exec sh -c 'make re -C "$1" $(dirname "$0")' {} \;
但它似乎不起作用,我收到此错误:
make: the `-C' option requires a non-empty string argument
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
-B, --always-make Unconditionally make all targets.
-C DIRECTORY, --directory=DIRECTORY
[...]
但是当我替换make re -C
为echo
or时printf
它工作正常......
find . -name "Makefile" -exec sh -c 'printf "%s\n" "$1" $(dirname "$0")' {} \;
# or
find . -name "Makefile" -exec sh -c 'echo "$1" $(dirname "$0")' {} \;
答案1
您的原始代码使用两个参数$0
和$1
,但您只在 中传递一些内容$0
,留空$1
。这会导致make
你以你所表现的方式抱怨。
你可以如果您愿意,可以通过简单地从您的命令中删除"$1"
(并引用周围的命令替换)来解决此问题,假设您不介意操作数和选项的顺序混合,但我也会给您一些其他想法。dirname
make
下面的两个命令查找Makefile
当前目录中或当前目录下调用的所有常规文件,然后用于在找到此类文件的每个目录中make -C
创建目标。re
find . -name Makefile -type f -exec sh -c 'make -C "${1%/*}" re' sh {} \;
或者
find . -name Makefile -type f -exec sh -c '
for pathname do
make -C "${pathname%/*}" re
done' sh {} +
在第二个命令中,我更改了sh -c
脚本以循环尽可能多的找到的路径名,而不仅仅是单个名称。
我已将dirname
这两个命令替换为标准参数扩展,该扩展从$pathname
.我们知道至少有一即使Makefile
在当前目录中找到该文件,路径名中也会包含斜杠,这使得此操作安全;否则这是一种边缘情况,您不想要更换dirname
更快的替代品。
一个不make
与其选项一起使用的更快速的变体是使用来自的(非标准)谓词-C
运行:make
-execdir
find
find . -name Makefile -type f -execdir make re \;
这会导致find
将工作目录更改为找到make
该文件的目录。Makefile
这个变体的好处是它make
直接执行而不处理sh -c
脚本。
答案2
与其使用它,不如直接进入目录make -C
更容易。cd
这个实现工作正常:
find . -name "Makefile" -exec sh -c 'cd "$(dirname "$0")" && make re' {} \;