从shell命令中分配Make中的宏值



I/O块大小将在我需要编写的Makefile中显着显示,因此我需要一种计算它的方法。这个脚本做了我想要的:

> cat blksz.bash
#!/bin/bash
bsl=$(du --block-size=1 testfile)
bsl=($bsl)
echo ${bsl[0]}

(有人可能有更好的方法,但如果你能容忍我,这不是这个问题最重要的一点。)

我可以从我的Makefile调用它,它工作得很好:

> cat Makefile
BLOCKSIZE := $(shell ./blksz.bash)
blocksize:
echo $(BLOCKSIZE)
> make blocksize
echo 4096
4096

然后我认为这是一个小脚本,是不是把它放在Makefile更好。但它不再工作。

> cat Makefile
BLOCKSIZE := $(shell bsl=$(du --block-size=1 testfile) ; 
bsl=($bsl) ; 
echo ${bsl[0]})
blocksize:
echo $(BLOCKSIZE)
> make blocksize
echo

BLOCKSIZE是没有定义的。显然,我在Makefile中错误地定义了shell命令。有人能告诉我正确的做法吗?此外,可能有更好的方法来获得块大小,但如何从shell命令中获得返回值,以便Makefile可以看到它的更广泛的问题可能会在某个时候再次出现,这基本上是我想要弄清楚的。

最后一件事,关于重复的问题,周围有一些类似的问题,但没有一个完全符合我的问题,AFAICT。我认为不同之处在于我在shell命令中使用了变量,并且不知何故它们的内容丢失了。

直接回答你的问题,$是一个特殊的字符(它引入了make变量和函数),所以如果你想把它传递给shell,你必须把它转义为$$。加上@tripleee提到的在/bin/sh中不可用的数组变量问题。

所以你的命令必须是:

BLOCKSIZE := $(shell /bin/bash -c 'bsl=$$(du --block-size=1 testfile) ; bsl=($$bsl) ; echo $${bsl[0]}').

我个人不喜欢使用bash特有的功能,也不喜欢awk,但YMMV。更好的方法是使用stat程序:

BLOCKSIZE := $(shell stat -c %s testfile)

如果你不想stat,那么另一种方法是:

BLOCKSIZE := ${shell set -- $$(du --block-size=1 testfile); echo $$1}

除非您破解SHELL=/bin/bash,否则您的shell命令将由/bin/sh执行。但是你不需要Bash。

BLOCKSIZE := $(shell du --block-size=1 testfile | awk '{ print $$1 }')

最新更新