为什么Bash-in-Makefile表达式不起作用?

时间:2021-07-08 07:03:21

Directly pasted into my shell, the following tries each of the 3 regex and works (see the *.{jpg,png,gis.tif}):

直接粘贴到我的shell中,以下尝试3个正则表达式中的每一个并且有效(参见*。{jpg,png,gis.tif}):

for file in ./output/India/*.{jpg,png,gis.tif}; do echo $file; openssl base64 -in $file -out ./output/India/`basename $file`.b64; done;

As a makefile process, it fails and returns :

作为makefile进程,它失败并返回:

task: 
  for file in ./output/India/*.{png,jpg,gis.tif} ; \
    do echo $$file ; openssl base64 -in $$file -out ./output/India/`basename $$file`.b64; \
  done

and returns :

并返回:

47910543179104:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('./output/India/*.{png,jpg,gis.tif}','r')

Why this expression doesn't work when the Bash is in a makefile ?

为什么当Bash在makefile中时这个表达式不起作用?

2 个解决方案

#1


I have been prompted to give a sketch of how make could do the heavy lifting for you.

我被提示给出一个草图,说明制造如何为你做繁重的工作。

So, you want to convert all the source files (.jpg, .png, .gis.tif) in output/India/ into their base64 encoded equivalents. A sketch:

因此,您希望将output / India /中的所有源文件(.jpg,.png,.gis.tif)转换为其base64编码的等效文件。草图:

.PHONY: all
all: # default target

dir := output/India/
exts := jpg png gis.tif
wildcards := $(addprefix ${dir}*.,${exts})
sources := $(wildcard ${wildcards})
targets := $(addsuffix .b64,${sources})

${targets}: %.b64: %
     openssl base64 -in $< -out $@

all: ${targets}
all: ; : $@ Success

This is more verbose than it needs to be, and normally I rail against the use of $(wildcard …). Oh well.

这比它需要的更冗长,通常我反对使用$(通配符......)。那好吧。

So what advantages do we have here over the shell version?

那么我们在shell版本上有什么优势呢?

  1. make -j5 will do 5 conversions at once. Good if you have four CPUs
  2. make -j5将同时进行5次转换。好的,如果你有四个CPU

  3. The conversion stops on the first error (like disk full say)
  4. 转换在第一个错误时停止(就像磁盘完全说的那样)

  5. Files that have not changed since their last conversion are not re-converted
  6. 自上次转换后未更改的文件不会重新转换

  7. No dodgy shell syntax (though sh is a big part of make)
  8. 没有狡猾的shell语法(虽然sh是make的重要部分)

UNTESTED BTW. Sorry.

未完成的BTW。抱歉。

#2


make uses /bin/sh by default and it doesn't support brace expansions.

默认情况下使用/ bin / sh,它不支持大括号扩展。

Either tell make to use a different shell by setting the SHELL variable inside the makefile, don't use brace expansions in the make rules, or run a script instead of an inline recipe (which script can be run by bash/etc.).

通过在makefile中设置SHELL变量来告诉make使用不同的shell,不要在make规则中使用大括号扩展,或者运行脚本而不是内联配方(哪个脚本可以由bash / etc运行)。

#1


I have been prompted to give a sketch of how make could do the heavy lifting for you.

我被提示给出一个草图,说明制造如何为你做繁重的工作。

So, you want to convert all the source files (.jpg, .png, .gis.tif) in output/India/ into their base64 encoded equivalents. A sketch:

因此,您希望将output / India /中的所有源文件(.jpg,.png,.gis.tif)转换为其base64编码的等效文件。草图:

.PHONY: all
all: # default target

dir := output/India/
exts := jpg png gis.tif
wildcards := $(addprefix ${dir}*.,${exts})
sources := $(wildcard ${wildcards})
targets := $(addsuffix .b64,${sources})

${targets}: %.b64: %
     openssl base64 -in $< -out $@

all: ${targets}
all: ; : $@ Success

This is more verbose than it needs to be, and normally I rail against the use of $(wildcard …). Oh well.

这比它需要的更冗长,通常我反对使用$(通配符......)。那好吧。

So what advantages do we have here over the shell version?

那么我们在shell版本上有什么优势呢?

  1. make -j5 will do 5 conversions at once. Good if you have four CPUs
  2. make -j5将同时进行5次转换。好的,如果你有四个CPU

  3. The conversion stops on the first error (like disk full say)
  4. 转换在第一个错误时停止(就像磁盘完全说的那样)

  5. Files that have not changed since their last conversion are not re-converted
  6. 自上次转换后未更改的文件不会重新转换

  7. No dodgy shell syntax (though sh is a big part of make)
  8. 没有狡猾的shell语法(虽然sh是make的重要部分)

UNTESTED BTW. Sorry.

未完成的BTW。抱歉。

#2


make uses /bin/sh by default and it doesn't support brace expansions.

默认情况下使用/ bin / sh,它不支持大括号扩展。

Either tell make to use a different shell by setting the SHELL variable inside the makefile, don't use brace expansions in the make rules, or run a script instead of an inline recipe (which script can be run by bash/etc.).

通过在makefile中设置SHELL变量来告诉make使用不同的shell,不要在make规则中使用大括号扩展,或者运行脚本而不是内联配方(哪个脚本可以由bash / etc运行)。