通过 shell 命令在 Make 中分配宏值
Assigning a macro value in Make from a shell command
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 命令中获取 return 值以便 Makefile 可以看到它可能会再次出现在某个时候,这就是我想要弄清楚的根本。
最后一件事,关于重复的问题,周围有一些类似的问题,但没有什么能完全满足我的要求,AFAICT。我认为不同之处在于我在 shell 命令中使用变量 within,但不知何故它们的内容丢失了。
除非你破解 SHELL=/bin/bash
你的 shell 命令将由 /bin/sh
执行。但是你不需要Bash。
BLOCKSIZE := $(shell du --block-size=1 testfile | awk '{ print $ }')
直接回答你的问题,$
是一个特殊的字符 make(它引入了 make 变量和函数)所以如果你想将它传递给 shell 你必须将它转义为$$
。加上 @tripleee 提到的数组变量在 /bin/sh
中不可用的问题。
所以你的命令必须是:
BLOCKSIZE := $(shell /bin/bash -c 'bsl=$$(du --block-size=1 testfile) ; bsl=($$bsl) ; echo $${bsl[0]}').
就我个人而言,我不喜欢使用 bash 特定的功能,也不喜欢使用 awk,而是 YMMV。执行此 IMO 的更好方法是使用 stat
程序:
BLOCKSIZE := $(shell stat -c %s testfile)
如果您不想 stat
,那么另一种方法是:
BLOCKSIZE := ${shell set -- $$(du --block-size=1 testfile); echo $}
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 命令中获取 return 值以便 Makefile 可以看到它可能会再次出现在某个时候,这就是我想要弄清楚的根本。
最后一件事,关于重复的问题,周围有一些类似的问题,但没有什么能完全满足我的要求,AFAICT。我认为不同之处在于我在 shell 命令中使用变量 within,但不知何故它们的内容丢失了。
除非你破解 SHELL=/bin/bash
你的 shell 命令将由 /bin/sh
执行。但是你不需要Bash。
BLOCKSIZE := $(shell du --block-size=1 testfile | awk '{ print $ }')
直接回答你的问题,$
是一个特殊的字符 make(它引入了 make 变量和函数)所以如果你想将它传递给 shell 你必须将它转义为$$
。加上 @tripleee 提到的数组变量在 /bin/sh
中不可用的问题。
所以你的命令必须是:
BLOCKSIZE := $(shell /bin/bash -c 'bsl=$$(du --block-size=1 testfile) ; bsl=($$bsl) ; echo $${bsl[0]}').
就我个人而言,我不喜欢使用 bash 特定的功能,也不喜欢使用 awk,而是 YMMV。执行此 IMO 的更好方法是使用 stat
程序:
BLOCKSIZE := $(shell stat -c %s testfile)
如果您不想 stat
,那么另一种方法是:
BLOCKSIZE := ${shell set -- $$(du --block-size=1 testfile); echo $}