如何从目标的外部shell调用设置Makefile变量
我需要逐行从某个文本文件中读取文件列表,然后将其转换为如何从目标的外部shell调用设置Makefile变量,shell,makefile,Shell,Makefile,我需要逐行从某个文本文件中读取文件列表,然后将其转换为-a filename1-a filename2-a filename3的顺序。 我尝试过这样做,但在这种情况下,setting FILES变量的语法似乎是错误的: files_pack: @while read -r file; do \ FILES += "-a $$file"; \ done <$(LIST_FILE) some_util $(FILES) 文件包: @读取-r文件时;做
-a filename1-a filename2-a filename3
的顺序。
我尝试过这样做,但在这种情况下,setting FILES变量的语法似乎是错误的:
files_pack:
@while read -r file; do \
FILES += "-a $$file"; \
done <$(LIST_FILE)
some_util $(FILES)
文件包:
@读取-r文件时;做\
FILES+=“-a$$文件”\
已完成的Shell分配在=
/+=
周围不能有空格
另外,$(文件)
将通过make进行扩展。您需要“$${FILES[@]}”
在那里
我还修改了您的代码以使用数组而不是字符串,这样名称中带有空格/等的文件可以正常工作
files_pack:
@while read -r file; do \
FILES+=(-a "$$file"); \
done <$(LIST_FILE)
some_util "$${FILES[@]}"
或全球:
SHELL := /bin/bash
Shell分配在=
/+=
周围不能有空格
另外,$(文件)
将通过make进行扩展。您需要“$${FILES[@]}”
在那里
我还修改了您的代码以使用数组而不是字符串,这样名称中带有空格/等的文件可以正常工作
files_pack:
@while read -r file; do \
FILES+=(-a "$$file"); \
done <$(LIST_FILE)
some_util "$${FILES[@]}"
或全球:
SHELL := /bin/bash
如果列表文件每行有一个文件,您需要做的就是在每行前面加上-a
,那么您需要的是
files_pack:
some_util $$(sed 's/^/-a /' $(LIST_FILE))
如果列表文件每行有一个文件,您需要做的就是在每行前面加上-a
,那么您需要的是
files_pack:
some_util $$(sed 's/^/-a /' $(LIST_FILE))
这也有效:
FILES=$(shell cat${LIST\u文件)
FILES_OPT=$(addprefix-a,${FILES})
此解决方案不依赖于bash,适用于所有通用shell,并且不需要安装“sed”。此解决方案也适用于:
FILES=$(shell cat${LIST\u文件)
FILES_OPT=$(addprefix-a,${FILES})
此解决方案不依赖于bash,适用于所有通用shell,并且不需要安装“sed”。受此启发,一个简单的解决方案可用于任何shell,但如果文件名包含空格或元字符,则会失败:
files_pack:
some_util $(shell printf " -a %s" $$(cat $(FILES)))
这可以改进为处理带有空格或撇号以外的特殊字符的文件名:
files_pack:
some_util $(shell IFS="$$(printf '\n+')"; IFS="$${IFS%+}"; printf " -a '%s'" $$(cat $(FILES)))
将IFS
设置为换行符+然后删除+的特殊顺序,是我所知道的唯一一种Posix兼容的方式,可以将IFS
设置为一个不涉及带物理换行符的命令行的换行符。(简单的命令替换会删除后续换行符,而不管IFS
的设置如何)
使用bash,可以使用%q
printf格式(以及一些其他bash简化格式)简化并使其更加健壮:
文件\u pack:SHELL:=/bin/bash
一些_util$(shell IFS=$$'\n';printf“-a%q”$$(的灵感来源于一个简单的解决方案,该解决方案可用于任何shell,但如果文件名包含空格或元字符,则会失败:
files_pack:
some_util $(shell printf " -a %s" $$(cat $(FILES)))
这可以改进为处理带有空格或撇号以外的特殊字符的文件名:
files_pack:
some_util $(shell IFS="$$(printf '\n+')"; IFS="$${IFS%+}"; printf " -a '%s'" $$(cat $(FILES)))
将IFS
设置为换行符+然后删除+的特殊顺序,是我所知道的唯一一种Posix兼容的方式,可以将IFS
设置为一个不涉及带物理换行符的命令行的换行符。(简单的命令替换会删除后续换行符,而不管IFS
的设置如何)
使用bash,可以使用%q
printf格式(以及一些其他bash简化格式)简化并使其更加健壮:
文件\u pack:SHELL:=/bin/bash
一些_util$(shell IFS=$$'\n';printf“-a%q”$$(FILES+=
是否为有效的shell语法?@Jens True。这需要makefile中的shell=/bin/bash
才能保证工作。+=
添加到bash
3.1中。FILES+=
是否为有效的shell语法?@Jens True。这需要makefile中的shell=/bin/bash
才能保证工作。
是在bash
3.1中添加的。在行内容中添加单引号可能也是个好主意(如果名称中有空格)但这实际上并不安全,因为它们也可能包含单引号,这将结束参数并重新引入空格/任意命令执行等问题。在行内容中添加单引号可能也是一个好主意(如果名称中有空格)但这实际上并不安全,因为它们也可能包含单引号,这将结束参数并重新引入空格/任意命令执行等问题。它也不能/不能处理带有空格的文件名。它也不能/不能处理带有空格的文件名。我想知道,是否也可以处理不同的文件结尾ings-/r/n
和列表文件中的/n
?@AntonKochkov:当然,您只需将\r
添加到IFS
(当然,这也会将\r
本身识别为行尾,但通常这不是问题。)我想知道,是否也可以处理不同的文件结尾-/r/n
和列表文件中的/n