RPM构建时%file段if语法不生效及报错问题咨询
RPM构建时%file段中if语法未被识别的解决方案
嘿,这个问题我碰到过好几次了——你犯了个典型的错误:把Shell的条件判断逻辑直接塞进了RPM spec的%file段里。
RPM的%file段是专门用来声明包要包含的文件/目录路径的,它会逐行解析每一条内容,把它们都当作待打包的文件路径处理。所以你写的if、!这些Shell关键字,还有后面的命令,全被RPM当成了奇怪的文件路径,自然会抛出一堆诸如File must begin with "/": if、Two files on one line: /usr/bin/getent的错误。
正确的解决思路
要实现根据系统用户存在情况动态定义bindir的需求,你得把条件判断逻辑移到**RPM构建的预处理阶段(%prep)或者安装前脚本(%pre)**中,提前完成bindir的全局定义,然后在%file段里直接引用这个预定义好的变量就行。
修改后的Spec代码示例
方案1:构建时判断(推荐,适合用户在构建机器上已存在的场景)
把判断逻辑放在%prep阶段,提前定义全局宏:
%prep # 提前判断用户存在性,定义bindir宏 if ! /usr/bin/getent passwd sgate >/dev/null; then %global bindir /home/sgate/elasticsearch elif ! /usr/bin/getent passwd rgate >/dev/null; then %global bindir /home/rgate/elasticsearch fi # 你的其他%prep逻辑... # 然后在%file段直接引用变量 %files %{bindir}/ # 其他需要打包的文件/目录...
方案2:安装时判断(适合用户可能在构建后才创建的场景)
如果需要在目标机器安装时才判断用户存在性,就得把变量写入RPM的宏文件,让%file段能读取到:
%pre # 安装时判断用户,写入全局宏文件 if ! /usr/bin/getent passwd sgate >/dev/null; then echo "%global bindir /home/sgate/elasticsearch" > %{_rpmconfigdir}/macros.local elif ! /usr/bin/getent passwd rgate >/dev/null; then echo "%global bindir /home/rgate/elasticsearch" > %{_rpmconfigdir}/macros.local fi # 其他%pre逻辑... %files %{bindir}/ # 其他需要打包的文件/目录...
额外注意点
- 用
%global代替%define:%global的作用域是整个spec文件,比%define的局部作用域更适合这种全局变量的定义。 - %file段里只能有合法的文件/目录路径,绝对不能出现任何Shell语法,所有动态逻辑都要提前在其他阶段处理好。
内容的提问来源于stack exchange,提问作者Rajkumar Cj
相关产品推荐
相关产品推荐

