bash 使用 RPM 规范文件中的脚本定义版本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33771728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 13:54:40  来源:igfitidea点击:

Define Version with script in RPM spec file

bashrpmrpmbuildsoftware-packagingrpm-spec

提问by Jimmie

I have an RPM Spec file, building on rhel7 with rpmbuild, where I would like to define the Version with a script.

我有一个 RPM Spec 文件,使用 rpmbuild 在 rhel7 上构建,我想在其中使用脚本定义版本。

I read here http://www.techrepublic.com/article/rpmproc-spec-file/, That I can do this:

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

%define version 1.2

Version: %{version}

And here RPM spec file - Is it possible to dynamically populate a spec file variable, That I can define with a script:

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

%define whoami %(cmd)

So I tried to do this in my Spec File:

所以我试图在我的规范文件中做到这一点:

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

Version: %{version}  **Line 23**

But I get a

但我得到一个

error: line 23: Empty tag: Version:

Things I have tested so far:

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

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

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

These work well, So I have no idea what it could be thats causing it to fail. Any ideas what could be casuing it to fail when I call the same thing in define tag in spec file?

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

Update

更新

I tried replacing the file name with the actual value so it looks like this

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

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

That works when called in terminal but as a

这在终端调用时有效,但作为

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

but I still get the

但我仍然得到

Empty tag: Version: Error

Update 2

更新 2

I tested a different more complex command then echo "12":

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

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

This works ok too! Makes the version the 7 first digits of the commit hash.

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

Update 3

更新 3

The mystery continues, I did a test to check if its the sed command thats the cause but the following command gives me 1.2 as the version

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

%define version %(echo "$( sed 's/.*= //' <<< "appVersion = 1.2" )")

If this command works but not my first one, then its got to be with something in my first command that only works when called directly in terminal and not in %(cmd). Getting closer!

如果此命令有效但不是我的第一个命令,那么它必须与我的第一个命令中的某些内容一起使用,该命令仅在终端中直接调用时才有效,而在 %(cmd) 中无效。越来越近!

Update 4

更新 4

Ok so I seem to have isolated what it must be, curious, looks like it could be the -nor the s| | \1 |psyntax that rpmbuild doesn't like. I made a more simpler version of my original. Check it out:

好的,所以我似乎已经隔离了它必须是什么,好奇,看起来它可能是rpmbuild 不喜欢-ns| | \1 |p语法。我做了一个更简单的原始版本。一探究竟:

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

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

Unfortunately though I don't think I can do anymore to isolate and figure out what the issue is. Theres nothing wrong with using a sed in the style of the second command but its still very interesting as to why the first command doesn't work.

不幸的是,尽管我认为我无法再隔离并找出问题所在。在第二个命令的样式中使用 sed 并没有错,但是对于为什么第一个命令不起作用仍然非常有趣。

Update 5

更新 5

I have discovered that there is some deep issue here when working with any script inside %() with a spec file and rpmbuild. I tried using awk just to see what would happen and it too breaks! This goes way deeper then I initially thought, like discovering a conspiracy:

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

#In terminal it prints 1.2-SNAPSHOT, but in Spec it's an error 
%define version %(echo "$(awk '/appVersion /{ print  }' <<< "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:

Update 6

更新 6

Good news and bad news for everyone, I found that rpm seems to be doing some of its own work in the backround and not showing what its doing, I finally found a command that gives different values when called through rpm:

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

%define version %(echo "$(awk '/midonetVersion /{ print  }' <<< "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 ""

So now I made an adjustment and called this:

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

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

So from looking at this, I think there maybe is a similar kind of behind the scenes parsing of the result of my first sed command from rpm. We will have our way rpm!

所以从这个角度来看,我认为可能有一种类似的幕后解析来自 rpm 的第一个 sed 命令的结果。我们将有我们的方式rpm!

Final Update

最终更新

A truce was made with rpm, I am going to use this command instead:

与 rpm 达成了休战,我将改用此命令:

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

It does the same thing as my first command and works inside specfile setting the version number correctly. If anyone has any guess as to why the first command wouldn't run I would be thrilled to read it. Peace!

它与我的第一个命令执行相同的操作,并在规范文件中正确设置版本号。如果有人对为什么第一个命令不运行有任何猜测,我会很高兴阅读它。和平!

采纳答案by Prasanna

You must be having a shell script that invokes rpmbuild command. You can use that script to compute version (or for that matter, any command that you are trying to use in rpm spec file).

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

Change your original code,

更改您的原始代码,

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

to,

到,

%define version _VERSION_
Version: %{version}

and sed VERSIONto its computed value in the shell script that calls rpmbuild (before invoking rpmbuild). After the actual spec contents are dumped to some file, pass on that generated file to rpmbuild in the same shell script.

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

Here is a summary of the steps:

以下是这些步骤的摘要:

Assuming you have a builder.sh shell script that calls rpmbuild, follow below steps:

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

  1. Update your spec file to have VERSIONplaceholder string/macro as show above
  2. Move current rpm spec file to my_package_template.spec
  3. in builder.sh, run command(s) to get your version and save the version to a variable
  4. Use sed command on my_package_template.spec file to replace VERSIONby this computed version, and save the sed output to my_package.spec
  5. Pass my_package.spec to rpmbuild command.
  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 命令。

Repeat steps 1, 3 and 4 for replacing usage of any other shell commands inside your spec file.

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

回答by Aaron D. Marasco

I would do a wrapper script. That allows you to decide things like if it is a regular release or a development one, etc. Then you can pass the variables with the --defineoption - see this question for more options.

我会做一个包装脚本。这使您可以决定它是常规版本还是开发版本等。然后您可以使用--define选项传递变量-有关更多选项,请参阅此问题