2

RPM SPEC files know about package versions in both Requires: and Provides: tags, so inside a SPEC file it's easy to build proper dependency even with mangled names (e.g. to avoid conflicts and allow multiple versions of packages)

As an example package foo provides updated version:

Name: foox
Provides: foo = 2

and

Name: bar5
Requires: foo >= 2

works quite well - yum will not install bar5 unless foox is also installed.

My question - how can I query which package provides foo = 2 from command line?

From the man page of rpm it appears that

--whatprovides CAPABILITY

Query all packages that provide the CAPABILITY capability. 

--provides

List capabilities this package provides.

Would've sufficed.
I can rpm -q --provides <package name> and see the version.
I can even rpm -q --qf %{VERSION} <package name> and get only the version.
However, I can't rpm -q --whatprovides on the name and version to get the actual package name.

I have also tried rpm -q --provides foo but I only get the original foo = 1, even though foox is installed and provides foo = 2.

what I would like is the following magic:

$ rpm -q --whatprovides "foo = 2"
$ foox

1 Answer 1

4

That's close:

rpm -q --whatprovides "foo = 2"

but it does not accept a version. To get that, go back a step and format the output from

rpm -q --whatprovides foo

like this:

rpm -q --queryformat "%{VERSION}:%{NAME}\n" --whatprovides foo

and filter the result by grep (to select your "2"), and then through sed, to remove the extra version followed by a colon:

grep -E '/^2:/' | sed -e 's/^[^:]*://'

That gives just the package name. In practice, you would want the version, release and architecture to install the correct dependency.

For reference: 5.2.5. Determining which package provides a certain capability (Fedora RPM Guide)

Regarding OP's comment that awk would be simpler:

awk -F: '{ if ($1 == "2") print $2}'

I agree (but from habit working on configure scripts, use awk second to grep/sed, since it is a little less portable). However, if one wanted to check for packages with versions greater than or equal to a given value, awk would definitely be much simpler, e.g.,

awk -F: '{ if ($1 >= 2) print $2}'

That occurred to me this morning after I'd already left. But that type of comparison is probably more common in spec-files than exact matches. Also, quoting the "2" may force awk to treat it as a string rather than a number. That would not match version 2.0, but leaving it unquoted — and numeric — would let it match.

@dave-thompson-085 pointed out that enclosing the comparison within the action is unnecessary. That is, the part within { and } in the preceding is an action, for all lines (since no pattern is given). Quoting from mawk's manual page:

An AWK program is a sequence of pattern {action} pairs and user function definitions.

and then

   A pattern can be:
          BEGIN
          END
          expression
          expression , expression

An expression might be a regular expression, but could also be an comparison. His suggested improvement is

awk -F: '$1>=2{print $2}'
5
  • I'd compress the grep and sed to a single sed or awk, but this works. Thanks
    – Dani_l
    Nov 10, 2015 at 11:55
  • awk -F: '{ if ($1 == "2") print $2}'
    – Dani_l
    Nov 10, 2015 at 11:57
  • yes - I would have added awk if you had requested an inequality, but grep/sed are tools I use most because I start with the simplest tool (most portable) and work upward to meet constraints. Nov 10, 2015 at 21:50
  • Even briefer awk -F: '$1>=2{print $2}' (or == etc as needed). Nov 11, 2015 at 1:48
  • yes, that works too (I was keeping the changed version close to the suggested, to make it easier to compare). Nov 11, 2015 at 1:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .