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 }')