使用RPM spec文件中的脚本定义版本

Jim*_*mie 14 bash rpm software-packaging rpmbuild rpm-spec

我有一个RPM规范文件,在rhel7上使用rpmbuild构建,我想用脚本定义Version.

我在这里阅读http://www.techrepublic.com/article/rpmproc-spec-file/,我可以这样做:

%define version 1.2

Version: %{version}
Run Code Online (Sandbox Code Playgroud)

在这里RPM spec文件 - 是否可以动态填充spec文件变量,我可以用脚本定义:

%define whoami %(cmd)
Run Code Online (Sandbox Code Playgroud)

所以我试着在我的规范文件中这样做:

%define version %(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')")

Version: %{version}  **Line 23**
Run Code Online (Sandbox Code Playgroud)

但我得到了一个

error: line 23: Empty tag: Version:
Run Code Online (Sandbox Code Playgroud)

到目前为止我测试的东西:

%define version %(echo "12") --basic script works ok, version becomes 12

//As a command straight in terminal
$ echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')"
//returns 1.2
Run Code Online (Sandbox Code Playgroud)

这些工作得很好,所以我不知道是什么导致它失败.当我在spec文件中的define标签中调用相同的东西时,有什么想法可能会让它失败?

更新

我尝试用实际值替换文件名,所以它看起来像这样

echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' <<< "appVersion = \"1.2-SNAPSHOT\"" | sed 's/^\(.*\)-.*$/\1/')"
Run Code Online (Sandbox Code Playgroud)

这在终端中被呼叫但是作为一个

%(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' <<< "appVersion = \"1.2-SNAPSHOT\"" | sed 's/^\(.*\)-.*$/\1/')") 
Run Code Online (Sandbox Code Playgroud)

但我仍然得到了

Empty tag: Version: Error
Run Code Online (Sandbox Code Playgroud)

更新2

我测试了一个不同的更复杂的命令echo "12":

%define version %(echo "$(git log -1 | grep commit | awk -F"commit " '{print $2}' | cut -c1-8)")
Run Code Online (Sandbox Code Playgroud)

这也可以!使版本成为提交哈希的7位数字.

更新3

这个谜团继续,我做了一个测试来检查它的sed命令是否是原因,但是下面的命令给了我1.2版本

%define version %(echo "$( sed 's/.*= //' <<< "appVersion = 1.2" )")
Run Code Online (Sandbox Code Playgroud)

如果这个命令工作但不是我的第一个命令,那么它必须在我的第一个命令中有一些东西只能在直接在终端中调用而不在%(cmd)中调用.越来越近!

更新4

好吧,所以我似乎已经隔离了它必须是什么,好奇,看起来它可能是rpmbuild不喜欢-ns| | \1 |p语法或语法.我制作了原版的更简单版本.看看这个:

#Error, doesn`t set version to 1.2
%define version %(echo "$( sed -n 's|^.*-\(-*\)|\1|p' <<< "foo-1.2" )") 

#Works ok! sets version to 1.2
%define version %(echo "$( sed 's/.*= //' <<< "appVersion = 1.2" )") 
Run Code Online (Sandbox Code Playgroud)

不幸的是,虽然我认为我不能再做任何事情来孤立并找出问题所在.在第二个命令的样式中使用sed没有任何问题,但它仍然非常有趣,为什么第一个命令不起作用.

更新5

我发现在使用spec文件和rpmbuild处理%()内的任何脚本时,存在一些深层次的问题.我尝试使用awk只是为了看看会发生什么,它也会破坏!这比我最初想的更深入,比如发现一个阴谋:

#In terminal it prints 1.2-SNAPSHOT, but in Spec it's an error 
%define version %(echo "$(awk '/appVersion /{ print $3 }' <<< "appVersion = \"1.2-SNAPSHOT\"" | tr -d \")")

sh: -c: line 0: unexpected EOF while looking for matching `)'
sh: -c: line 1: syntax error: unexpected end of file
error: line 23: Empty tag: Version:
Run Code Online (Sandbox Code Playgroud)

更新6

对每个人来说都是好消息和坏消息,我发现rpm似乎在后台做了一些自己的工作而没有显示它的作用,我终于找到了一个命令,当通过rpm调用时给出不同的值:

%define version %(echo "$(awk '/midonetVersion /{ print $3 }' <<< "midonetVersion = \"5.1-SNAPSHOT\"")")
#In terminal it echos "5.1-SNAPSHOT" (literally wrapped in "" )
#When in spec it set version to 5.1-SNAPSHOT , rpmbuild is removing the ""
Run Code Online (Sandbox Code Playgroud)

所以现在我做了一个调整并称之为:

#echos "5.1 in terminal and sets version to 5.1 in spec
%define version %(echo "$(awk '/appVersion /{ print $3 }' <<< "appVersion = \"1.2-SNAPSHOT\"")"| cut -d'-' -f1)
Run Code Online (Sandbox Code Playgroud)

所以从这看起来,我认为可能有类似的幕后解析我的第一个sed命令从rpm的结果.我们将以我们的方式转速!

最后更新

使用rpm进行休战,我将使用此命令:

%define version %(echo "$(awk '/ appVersion =/{ print $3 }' /filepath/values.txt" | sed 's/\"//g' | cut -d'-' -f1)
Run Code Online (Sandbox Code Playgroud)

它与我的第一个命令做同样的事情,并在specfile中正确设置版本号.如果有人猜测为什么第一个命令不会运行,我会很高兴阅读它.和平!

Pra*_*nna 5

您必须有一个调用 rpmbuild 命令的 shell 脚本。您可以使用该脚本来计算版本(或者就此而言,您尝试在 rpm 规范文件中使用的任何命令)。

改变你原来的代码,

%define version %(echo "$(sed -n 's|^[ ]*appVersion = "\(.*\)"|\1|p' /fullfilepath/values.txt | sed 's/^\(.*\)-.*$/\1/')")
Version: %{version}
Run Code Online (Sandbox Code Playgroud)

到,

%define version _VERSION_
Version: %{version}
Run Code Online (Sandbox Code Playgroud)

并将 sed VERSION更改为调用 rpmbuild 的 shell 脚本中的计算值(在调用 rpmbuild 之前)。将实际规范内容转储到某个文件后,将生成的文件传递到同一 shell 脚本中的 rpmbuild。

以下是步骤摘要:

假设您有一个调用 rpmbuild 的 builder.sh shell 脚本,请按照以下步骤操作:

  1. 更新您的规范文件以具有VERSION占位符字符串/宏,如上所示
  2. 将当前 rpm 规范文件移至 my_package_template.spec
  3. 在 builder.sh 中,运行命令来获取您的版本并将版本保存到变量中
  4. 在 my_package_template.spec 文件上使用 sed 命令将VERSION替换为此计算版本,并将 sed 输出保存到 my_package.spec
  5. 将 my_package.spec 传递给 rpmbuild 命令。

重复步骤 1、3 和 4 以替换规范文件中任何其他 shell 命令的使用。

  • `rpmbuild` 允许从命令行设置变量,这比需要 `sed` 和临时文件要容易得多。 (8认同)