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

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}'
  • I'd compress the grep and sed to a single sed or awk, but this works. Thanks – Dani_l Nov 10 '15 at 11:55
  • awk -F: '{ if ($1 == "2") print $2}' – Dani_l Nov 10 '15 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. – Thomas Dickey Nov 10 '15 at 21:50
  • Even briefer awk -F: '$1>=2{print $2}' (or == etc as needed). – dave_thompson_085 Nov 11 '15 at 1:48
  • yes, that works too (I was keeping the changed version close to the suggested, to make it easier to compare). – Thomas Dickey Nov 11 '15 at 1:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.