I am writing a script that installs some packages and does some configuration work. I want the script to install a specific major version of a package, but I do not care which minor version of the package it is.

More to the point, I want it to install the latest 2.y.z release of the package, but not 1.y.z or 3.y.z (or any other major version number).

I have tried (without success)

  • zypper install 'mypackage=2'
  • zypper install 'mypackage>1<3'
  • zypper install 'mypackage>1' 'mypackage<3'
  • zypper install 'mypackage>=2.0.0' 'mypackage<3.0.0'

The last one seems promising, because then zypper complains:

'mypackage>=2.0.0' not found in package names. Trying capabilities. No provider of 'mypackage >= 2.0.0' found.

However, after that message, it still proceeds with installing mypackage-1.5.0, because that satisfies the second package-edition specified.

3 Answers 3



At first I experimented with SailorCire's answer here and came up with an improved version:

zypper search -t package -x -s PACKAGE | grep " MIN_NUM" | cut -d '|' -f 4 | tr -d '[:space:], then you can pipe it into zypper install by doing zypper install PACKAGE followed by backticks-surrounded command above.

For example, this will install php7-pear 1.*:

zypper -n in --details php7-pear-`zypper search -t package -x -s php7-pear | grep " 1." | cut -d '|' -f 4 | tr -d '[:space:]'`


But then I came up with a better solution. Rather than target a specific version with hacks like this, we can exclude versions without hacks using zypper addlock with version constraints.

So, what OP wants is actually this:

zypper addlock "mypackage < 2"
zypper addlock "mypackage >= 3"

These will prevent mypackage installs with versions <2 or >=3.


From the man page

install (in) [options] name|capability|rpm_file_uri...
           Install or update packages.

           The packages can be selected by their name or by a capability they provide.

               A capability is formed by "NAME[.ARCH][ OP EDITION]", where ARCH is an architecture code, OP is one of =, or > and EDITION is "VERSION[-RELEASE]". For example: zypper=0.8.8-2 The NAME component of a
               capability is not only a package name but any symbol provided by packages: /bin/vi, libcurl.so.3, perl(Time::ParseDate). Just remember to quote to protect the special characters from the shell, for example:
               zypper\>0.8.10 or 'zypper>0.8.10'.

               If EDITION is not specified, the newest installable version will be installed. This also means that if the package is already installed and newer versions are available, it will get upgraded to the newest installable

               If ARCH is not specified, or the last dot of the capability name string is not followed by known architecture, the solver will treat the whole string as a capability name. If the ARCH is known, the solver will select
               a package matching that architecture and complain if such package cannot be found.

Since it says one of the following and I don't see any conjunction operator, I'll say that it can't be done natively.

You could always script it with something like

zypper se -n -s package | grep " package " | grep " MIN_NUM" | cut -d '|' -f 4

Do note: that the above is very lazy and should be better written.

Also note: you should make a feature request. :)

  • Better version of this: zypper search -t package -x -s PACKAGE | grep " MIN_NUM" | cut -d '|' -f 4 | tr -d '[:space:], then you can pipe it into zypper install by doing zypper install PACKAGE followed by backticks-surrounded command above. Mar 4, 2020 at 20:15

In case someone needs a working example, here is one.

In my case, I needed to install binutils, but only in "2.39-something" version.
It's a good-enough non-interactive solution, worked even in a Dockerfile.

export PACKAGE='binutils'
export MAJOR='2.39'

export ZYPP='zypper --non-interactive'
${ZYPP} ref
export LATEST="$(${ZYPP} --no-refresh se -s -x -t package $PACKAGE \
  | cut -d '|' -f 4 | fgrep -- $MAJOR | sed -e 's/[[:space:]]*//g' \
  | sort -n | head -n 1 | tr -d '\n')"
${ZYPP} in -y --no-recommends --force "$PACKAGE-$LATEST"
${ZYPP} al -- "$PACKAGE"
${ZYPP} up -y --no-recommends


  • in [...] --force necessary to prevent selection of "any" other version
  • se [...] -x: only exact matches
  • al lock the installed package, so that further installs wouldn't overwrite it with newer version
  • very special case: should some packages be installed from not-yet-imported repository, add this option to the ZYPP variable: --gpg-auto-import-keys
  • don't repeat my mistake: --color option messed up the sub-shell logic
  • I was lucky, that there weren't multiple packages which match the exact query binutils, otherwise more complex magic would be required

You must log in to answer this question.

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