zypper 命令详解与参数实测(openSUSE Leap 16.0)

在 openSUSE Leap 16.0(zypper 1.14.101)逐项实测 zypper 全流程:refresh、install/remove、update/patch/dup、search/info、软件源管理、clean/verify、全局选项与退出码,含服务托管源寻址、GPG 签名信任、本地软件源搭建实战与常见问题排查。

Linux命令Linux系统命令行包管理2026/10/17

zypper 命令详解与参数实测(openSUSE Leap 16.0)

目标:全面掌握 zypper 的每一个常用命令与参数——软件源管理(refresh/repos/addrepo/modifyrepo/removerepo)、软件管理(install/remove/verify/search/info/clean)、更新与补丁(update/list-updates/patch/list-patches/patch-check/dist-upgrade)、全局选项(-y/-n/-q/-v/-t/-x/--no-gpg-checks)、包类型语义(package/patch/pattern/product)、退出码与报错行为,以及与 apt/yum/dnf/pacman/apk/emerge/xbps 的操作对照,全部命令与回显已在 openSUSE Leap 16.0(zypper 1.14.101)实测通过。

一、环境信息

本文所有命令均在以下环境实测,回显逐字照抄:

  • 操作系统:openSUSE Leap 16.0(PRETTY_NAME="openSUSE Leap 16.0")
  • 内核架构:x86_64
  • zypper 软件包:zypper-1.14.101-160000.1.1.x86_64
  • 包管理后端库:libzypp-17.38.16-160000.1.1.x86_64
  • 执行身份:root
  • 系统状态:最小化安装(rpm -qa | wc -l 实测 121 个软件包),无图形界面
  • 演示软件包:tree、sl、bc、htop、zip、jq(含依赖 libjq1、libonig5)、lsof、createrepo_c
  • 软件源:由 openSUSE 服务(ris 类型)托管,默认启用 repo-oss 与 repo-openh264
$ cat /etc/os-release
NAME="openSUSE Leap"
VERSION="16.0"
ID="opensuse-leap"
ID_LIKE="suse opensuse"
VERSION_ID="16.0"
PRETTY_NAME="openSUSE Leap 16.0"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:16.0"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
DOCUMENTATION_URL="https://en.opensuse.org/Portal:Leap"
LOGO="distributor-logo-Leap"

$ zypper --version
zypper 1.14.101

$ rpm -q zypper libzypp
zypper-1.14.101-160000.1.1.x86_64
libzypp-17.38.16-160000.1.1.x86_64

💡 说明: Leap 16.0 的产品包名是 Leap-release(可用 rpm -q Leap-release 确认),而非旧版的 openSUSE-release,在最小化环境里直接 rpm -q openSUSE-release 会报 not installed,初学者容易误判为「版本不完整」。查版本更稳的做法是 zypper --version 与 cat /etc/os-release 组合。

二、命令概览

2.1 语法形态与全局选项速查

zypper 的语法有两种形态(来自实测 zypper --help 首部):

Usage:

    zypper [--GLOBAL-OPTIONS] <COMMAND> [--COMMAND-OPTIONS] [ARGUMENTS]
    zypper <SUBCOMMAND> [--COMMAND-OPTIONS] [ARGUMENTS]
  • 第一种:全局选项在命令之前,如 zypper -q search tree;
  • 第二种:zypper 直接接子命令,全局选项留在原位即可省略。

实测提取的高频全局选项速查表:

选项作用实测要点
--quiet, -q只输出错误消息,抑制过程行表格结果仍会输出,仅省略 Refreshing/Loading 过程行
--verbose, -v提高输出详细程度(调试用 -vv)会打印 Verbosity: 2 及 repomd.xml 下载详情
--non-interactive, -n不提问,自动采用默认答案脚本化首选;与 -y 等价的命令选项见 install 帮助
--xmlout, -xXML 输出机器消费场景(监控、CI)直接解析
--terse, -t紧凑输出(implies --no-abbrev --no-color)面向脚本的表格输出
--no-gpg-checks忽略 GPG 检查失败继续执行未签名软件源场景,实测见 3.16
--gpg-auto-import-keys自动信任并导入新软件源签名密钥免交互密钥导入
--dry-run, -D 是全局能力不改动系统,只报告将做什么注意:配合 --download-only 才能做完整文件冲突检查
--root, -R <DIR>指定根目录(修复异构系统)chroot 维护场景
--reposd-dir, -D <DIR>使用其他 .repo 定义目录多套软件源配置切换

💡 说明: zypper 的 -t 是全局「terse」选项,同时 -t 在 install/search/info 等命令里又是「类型 type」的命令选项,两者不冲突(一个是全局位置、一个是命令位置),但写脚本时容易混淆。判断技巧:跟在 zypper 后面的是全局选项,跟在子命令后面的是命令选项,如 zypper -t in -t package tree 中第一个 -t 是 terse、第二个才是 type。

2.2 --help 全量输出(逐行照抄)

先看完整帮助,是逐命令实测的地图。以下为 zypper --help 的完整实测输出:

$ zypper --help

Usage:

    zypper [--GLOBAL-OPTIONS] <COMMAND> [--COMMAND-OPTIONS] [ARGUMENTS]
    zypper <SUBCOMMAND> [--COMMAND-OPTIONS] [ARGUMENTS]

Global Options:

    --help, -h              Help.
    --version, -V           Output the version number.
    --promptids             Output a list of zypper's user prompts.
    --config, -c <FILE>     Use specified config file instead of the default.
    --userdata <STRING>     User defined transaction id used in history and plugins.
    --quiet, -q             Suppress normal output, print only error messages.
    --verbose, -v           Increase verbosity. For debugging output specify this option twice.
                            'zypper -vv ref' for example will show the mirrors used to download the
                            metadata.
    --color
    --no-color              Whether to use colors in output if tty supports it.
    --no-abbrev, -A         Do not abbreviate text in tables. Default: false
    --table-style, -s <INTEGER>
                            Table style (0-11).
    --non-interactive, -n   Do not ask anything, use default answers automatically. Default: false
    --non-interactive-include-reboot-patches
                            Do not treat patches as interactive, which have the rebootSuggested-flag
                            set. Default: false
    --xmlout, -x            Switch to XML output.
    --ignore-unknown, -i    Ignore unknown packages. Default: false
    --terse, -t             Terse output for machine consumption. Implies --no-abbrev and
                            --no-color.


    --reposd-dir, -D <DIR>  Use alternative repository definition file directory.
    --servicesd-dir <DIR>   Use alternative services definition file directory.
    --cache-dir, -C <DIR>   Use alternative directory for all caches.
    --raw-cache-dir <DIR>   Use alternative raw meta-data cache directory.
    --solv-cache-dir <DIR>  Use alternative solv file cache directory.
    --pkg-cache-dir <DIR>   Use alternative package cache directory.

  Repository Options

    --no-gpg-checks         Ignore GPG check failures and continue. Default: false
    --gpg-auto-import-keys  Automatically trust and import new repository signing keys.
    --plus-repo, -p <URI>   Use an additional repository.
    --plus-content <TAG>    Additionally use disabled repositories providing a specific keyword. Try
                            '--plus-content debug' to enable repos indicating to provide debug
                            packages.
    --disable-repositories  Do not read meta-data from repositories.
    --no-refresh            Do not refresh the repositories.
    --no-cd                 Ignore CD/DVD repositories.
    --no-remote             Ignore remote repositories.
    --releasever            Set the value of $releasever in all .repo files (default: distribution
                            version)

  Target Options

    --root, -R <DIR>        Operate on a different root directory.
    --installroot <DIR>     Operate on a different root directory, but share repositories with the
                            host.
    --disable-system-resolvables
                            Do not read installed packages.

Commands:

      help, ?               Print zypper help
      shell, sh             Accept multiple commands at once.

  Repository Management:

      repos, lr             List all defined repositories.
      addrepo, ar           Add a new repository.
      removerepo, rr        Remove specified repository.
      renamerepo, nr        Rename specified repository.
      modifyrepo, mr        Modify specified repository.
      refresh, ref          Refresh all repositories.
      clean, cc             Clean local caches.

  Service Management:

      services, ls          List all defined services.
      addservice, as        Add a new service.
      modifyservice, ms     Modify specified service.
      removeservice, rs     Remove specified service.
      refresh-services, refs
                            Refresh all services.

  Software Management:

      install, in           Install packages.
      remove, rm            Remove packages.
      removeptf, rmptf      Remove (not only) PTFs.
      verify, ve            Verify integrity of package dependencies.
      source-install, si    Install source packages and their build dependencies.
      install-new-recommends, inr
                            Install newly added packages recommended by installed packages.

  Update Management:

      update, up            Update installed packages with newer versions.
      list-updates, lu      List available updates.
      patch                 Install needed patches.
      list-patches, lp      List available patches.
      dist-upgrade, dup     Perform a distribution upgrade.
      patch-check, pchk     Check for patches.

  Querying:

      search, se            Search for packages matching a pattern.
      info, if, show        Show full information for specified packages.
      patch-info            Show full information for specified patches.
      pattern-info          Show full information for specified patterns.
      product-info          Show full information for specified products.
      patches, pch          List all available patches.
      packages, pa          List all available packages.
      patterns, pt          List all available patterns.
      products, pd          List all available products.
      what-provides, wp     List packages providing specified capability.

  Package Locks:

      addlock, al           Add a package lock.
      removelock, rl        Remove a package lock.
      locks, ll             List current package locks.
      cleanlocks, cl        Remove useless locks.

  Locale Management:

      locales, lloc         List requested locales (languages codes).
      addlocale, aloc       Add locale(s) to requested locales.
      removelocale, rloc    Remove locale(s) from requested locales.

  Other Commands:

      versioncmp, vcmp      Compare two version strings.
      targetos, tos         Print the target operating system ID string.
      licenses              Print report about licenses and EULAs of installed packages.
      download              Download rpms specified on the commandline to a local directory.
      source-download       Download source rpms for all installed packages to a local directory.
      needs-rebooting       Check if the reboot-needed flag was set.
      ps                    List running processes which might still use files and libraries deleted
                            by recent upgrades.
      purge-kernels         Remove old kernels.
      system-architecture   Print the detected system architecture.

  Subcommands:

      subcommand            Lists available subcommands.

Type 'zypper help <COMMAND>' to get command-specific help.

2.3 常用子命令与别名速查

zypper 每个命令都有全称与短别名两种写法,实测常用对照如下(「实测」列表示本文是否实际执行过该形式):

全称别名用途实测形式
refreshref刷新软件源元数据zypper refresh、zypper ref、zypper ref -f
reposlr列出软件源zypper repos、zypper lr -d
addrepoar添加软件源zypper ar -c
modifyrepomr修改软件源属性zypper mr -d/-e/-p/-k/-K
removereporr删除软件源zypper rr、zypper removerepo
servicesls列出软件源服务zypper ls
installin安装软件包zypper in -y、zypper in -d、zypper in -f、zypper in -t
removerm卸载软件包zypper rm -y、zypper rm --clean-deps -y
updateup更新已安装包zypper up -D -y、zypper up -y
list-updateslu列出可更新包zypper lu
patchpatch安装全部待打补丁zypper patch -D --category security、zypper patch -y
list-patcheslp列出可用补丁zypper lp
patch-checkpchk补丁检查(有补丁时退出码 100)zypper pchk
dist-upgradedup发行版全量升级概念对照见 3.12
searchse搜索软件包zypper se、zypper se -s、zypper se -x、zypper se -d
infoif / show查看包详情zypper info tree、zypper if --requires
verifyve依赖完整性校验与修复zypper ve -D -y、zypper -n ve
cleancc清理缓存zypper clean、zypper clean -a
shellsh交互式连续执行多条命令printf ... | zypper shell
what-provideswp反查能力提供者(已弃用)zypper wp tree
versioncmpvcmp版本号比较zypper vcmp 1.2.3 1.10.0

2.4 测试数据准备

本文为避免污染系统,只使用小体积演示包并逐个回收:tree(84 KiB,目录树显示)、sl(18 KiB,趣味小火车)、bc(115 KiB,任意精度计算器)、htop(进程监视)、zip(260 KiB)、jq 及其依赖 libjq1/libonig5(共 410 KiB,JSON 处理)、lsof、createrepo_c(本地软件源构建工具)。所有安装/卸载操作均可独立复现,互不依赖的命令读者可单独执行。

另需准备一个本地目录 /srv/repo-local 用于 3.16 与 4.4 的本地软件源实战(由 createrepo_c 生成元数据),以及一个指向不可达地址的软件源 repo-bogus(http://127.0.0.1:1/bogus)用于排障演示,两者都在演示结束后删除。

💡 说明: jq 是演示「依赖解析/依赖清理/依赖修复」的理想样本——它本体 83.9 KiB,却会连带拉取 libjq1 与 libonig5 两个运行库,一装一卸之间把 zypper 的依赖管理完整走了一遍;而单独用 rpm 强拆 libonig5 又能制造出真实的「缺依赖」现场(见 3.14、4.3)。

三、参数逐项实测

3.1 refresh(ref):刷新软件源元数据

本节验证 refresh 的基本用法、强制刷新与失败场景。最小化环境首次刷新时连服务带软件源一起执行:

zypper refresh          # 刷新全部已启用软件源
zypper ref repo-oss     # 按别名刷新单个源(Leap 16 会报错,见下文)

实测回显(首次全量刷新,下载 repomd.xml 与索引):

$ zypper refresh
Refreshing service 'openSUSE'.
Retrieving repository 'repo-openh264 (16.0)' metadata [...
Looking for gpg keys in repository repo-openh264 (16.0).
  gpgkey=https://codecs.opensuse.org/openh264/openSUSE_Leap_16/repodata/repomd.xml.key
.......done]
Building repository 'repo-openh264 (16.0)' cache [....done]
Retrieving repository 'repo-oss (16.0)' metadata [...
Looking for gpg keys in repository repo-oss (16.0).
  gpgkey=http://cdn.opensuse.org/distribution/leap/16.0/repo/oss/x86_64/repodata/repomd.xml.key
............done]
Building repository 'repo-oss (16.0)' cache [....done]
All repositories have been refreshed.

再看排障实录——给系统加一个不可达软件源(http://127.0.0.1:1/bogus)后刷新,报错原文逐字如下:

$ zypper ref repo-bogus
Refreshing service 'openSUSE'.
Retrieving repository 'repo-bogus' metadata [.error]
Repository 'repo-bogus' is invalid.
[repo-bogus|http://127.0.0.1:1/bogus] Failed to retrieve new repository metadata.
History:
 - [|] Error trying to read from 'http://127.0.0.1:1/bogus'
 - Download (curl) error for 'http://127.0.0.1:1/bogus/content':
   Error code: Connection failed Curl error (7)
   Error message: Failed to connect to 127.0.0.1 port 1 after 0 ms: Could not connect to server
Please check if the URIs defined for this repository are pointing to a valid repository.
Skipping repository 'repo-bogus' because of the above error.
Could not refresh the repositories because of errors.
#### EXIT=4

定位路径很清晰:Repository ... is invalid → Failed to retrieve new repository metadata → History 里的 curl error 7(连接失败)→ 结论「URI 指向的不是有效软件源」。确认后 zypper rr repo-bogus 清理即可。同名不存在的源报错更简单:zypper ref nosuchrepo 返回 Repository 'nosuchrepo' not found by its alias, number, or URI.,退出码 3。

refresh 的主要命令选项(实测 zypper help refresh):

选项作用
-f, --force强制完整刷新(重新下载元数据并重建索引)
-b, --force-build只强制重建索引数据库
-d, --force-download只强制下载原始元数据
-r, --repo <ALIAS#|URI>只刷新指定源
-s, --services先刷新服务再刷新源

实测 -f 与 -s:

$ zypper ref -f openSUSE:repo-openh264
Refreshing service 'openSUSE'.
Forcing raw metadata refresh
Retrieving repository 'repo-openh264 (16.0)' metadata [...
Looking for gpg keys in repository repo-openh264 (16.0).
  gpgkey=https://codecs.opensuse.org/openh264/openSUSE_Leap_16/repodata/repomd.xml.key
.......done]
Forcing building of repository cache
Building repository 'repo-openh264 (16.0)' cache [....done]
Specified repositories have been refreshed.

$ zypper refresh -s
Refreshing service 'openSUSE'.
All services have been refreshed.
Repository 'repo-openh264 (16.0)' is up to date.
Repository 'repo-oss (16.0)' is up to date.
All repositories have been refreshed.

💡 说明: Leap 16.0 的软件源由 openSUSE 服务托管,别名带 openSUSE: 前缀,zypper ref repo-oss 这种旧式短别名会直接报 not found by its alias, number, or URI(退出码 3),必须写 openSUSE:repo-oss 或用编号 zypper ref 4。这是 Leap 16 迁移过程中最常见的坑,详见 3.2。

3.2 服务托管源:Leap 16 的新寻址规则

zypper lr 显示 Leap 16 的 6 个默认源都来自 openSUSE 服务(zypper ls 可见 ris 类型)。实测对这类源做任何按名操作,都必须用「完整别名」或「编号」:

$ zypper ref repo-oss
Refreshing service 'openSUSE'.
Repository 'repo-oss' not found by its alias, number, or URI.
Use 'zypper repos' to get the list of defined repositories.
Some of the repositories have not been refreshed because they were not known.
#### EXIT=3

$ zypper ref openSUSE:repo-oss
Refreshing service 'openSUSE'.
Repository 'repo-oss (16.0)' is up to date.
Specified repositories have been refreshed.
#### EXIT=0

$ zypper ref 4
Refreshing service 'openSUSE'.
Repository 'repo-oss (16.0)' is up to date.
Specified repositories have been refreshed.
#### EXIT=0

编号即 zypper lr 输出的 # 列(repo-oss 是 4)。对服务托管源做修改属性操作还会得到「易失」警告:

$ zypper mr -k openSUSE:repo-oss
RPM files caching has been enabled for repository 'openSUSE:repo-oss'. [volatile]
Warning: Repo 'openSUSE:repo-oss' is managed by service 'openSUSE'. Volatile changes are reset by the next service refresh!

💡 说明: [volatile] 与末尾 Warning 表明这条修改只落在本地缓存视图,下一次服务刷新(每次 zypper 都会先 Refreshing service 'openSUSE'.)就会重置回服务定义的值。要对 Leap 16 的默认源做持久化修改,需编辑 /etc/zypp/services.d/ 下对应的服务定义或改用独立 .repo 文件,而不是 mr。

3.3 repos(lr):查看软件源清单

zypper lr 的各种信息位由选项控制,实测全集:

$ zypper lr
Refreshing service 'openSUSE'.
Repository priorities are without effect. All enabled repositories share the same priority.

# | Alias                       | Name                      | Enabled | GPG Check | Refresh
--+-----------------------------+---------------------------+---------+-----------+--------
1 | openSUSE:repo-non-oss       | repo-non-oss (16.0)       | No      | ----      | ----
2 | openSUSE:repo-non-oss-debug | repo-non-oss-debug (16.0) | No      | ----      | ----
3 | openSUSE:repo-openh264      | repo-openh264 (16.0)      | Yes     | ( p) Yes  | Yes
4 | openSUSE:repo-oss           | repo-oss (16.0)           | Yes     | ( p) Yes  | Yes
5 | openSUSE:repo-oss-debug     | repo-oss-debug (16.0)     | No      | ----      | ----
6 | openSUSE:repo-oss-source    | repo-oss-source (16.0)    | No      | ----      | ----

-d 展示全部细节(URI、优先级、类型、所属服务):

$ zypper lr -d
# | Alias                       | Name                      | Enabled | GPG Check | Refresh | Keep | Priority | Type | URI                                                                      | Service
--+-----------------------------+---------------------------+---------+-----------+---------+------+----------+------+--------------------------------------------------------------------------+---------
1 | openSUSE:repo-non-oss       | repo-non-oss (16.0)       | No      | ----      | ----    | -    |   99     | N/A  | http://cdn.opensuse.org/distribution/leap/16.0/repo/non-oss/x86_64       | openSUSE
2 | openSUSE:repo-non-oss-debug | repo-non-oss-debug (16.0) | No      | ----      | ----    | -    |   99     | N/A  | http://cdn.opensuse.org/debug/distribution/leap/16.0/repo/non-oss/x86_64 | openSUSE
3 | openSUSE:repo-openh264      | repo-openh264 (16.0)      | Yes     | ( p) Yes  | Yes     | -    |   99     | N/A  | https://codecs.opensuse.org/openh264/openSUSE_Leap_16                    | openSUSE
4 | openSUSE:repo-oss           | repo-oss (16.0)           | Yes     | ( p) Yes  | Yes     | -    |   99     | N/A  | http://cdn.opensuse.org/distribution/leap/16.0/repo/oss/x86_64           | openSUSE
5 | openSUSE:repo-oss-debug     | repo-oss-debug (16.0)     | No      | ----      | ----    | -    |   99     | N/A  | http://cdn.opensuse.org/debug/distribution/leap/16.0/repo/oss/x86_64     | openSUSE
6 | openSUSE:repo-oss-source    | repo-oss-source (16.0)    | No      | ----      | ----    | -    |   99     | N/A  | http://cdn.opensuse.org/source/distribution/leap/16.0/repo/oss           | openSUSE

其余常用组合实测:lr -u -a -p(URI+别名+优先级三列齐出)、lr -E(只看已启用源,输出只剩 3、4 两行)、lr -k(Keep Packages 列)、lr -r(自动刷新标志列)。导出为 .repo 文件(迁移备份用,见 4.2):

$ zypper lr --export /root/demo-repos-backup.repo
Repositories have been successfully exported to /root/demo-repos-backup.repo.

导出的文件内容(节选):

# Repository 'openSUSE:repo-oss' is maintained by the 'openSUSE' service.
# Manual changes may be overwritten by a service refresh.
# See also 'man zypper', section 'Services'.
[openSUSE:repo-oss]
name=repo-oss (${releasever})
enabled=1
autorefresh=1
baseurl=http://cdn.opensuse.org/distribution/leap/${releasever}/repo/oss/$basearch
gpgkey=http://cdn.opensuse.org/distribution/leap/${releasever}/repo/oss/$basearch/repodata/repomd.xml.key
service=openSUSE

💡 说明: GPG Check 列的 ( p) Yes 表示「软件包仓库签名检查」已启用(p = package repo signature);被服务禁用的源显示 ----。lr 表头的 Enabled/Refresh 两个开关与 mr -d/-e/-f/-F 一一对应,排查「为什么这个源没被刷新」时先看这两列。

3.4 addrepo(ar):添加软件源

实测添加 non-oss 源,-c 先探测 URI 可达性,-n 给出可读名称:

$ zypper ar -c -n 'Leap 16.0 Demo Non-OSS' http://cdn.opensuse.org/distribution/leap/16.0/repo/non-oss/x86_64 repo-demo-nonoss
Adding repository 'Leap 16.0 Demo Non-OSS' [.....done]
Repository 'Leap 16.0 Demo Non-OSS' successfully added

URI         : http://cdn.opensuse.org/distribution/leap/16.0/repo/non-oss/x86_64
Enabled     : Yes
GPG Check   : Yes
Autorefresh : No
Priority    : 99 (default priority)

Repository priorities are without effect. All enabled repositories share the same priority.

两类失败实测。其一,重复别名:

$ zypper ar http://cdn.opensuse.org/distribution/leap/16.0/repo/non-oss/x86_64 repo-demo-nonoss
Adding repository 'repo-demo-nonoss' [...error]
Repository named 'repo-demo-nonoss' already exists. Please use another alias.
#### EXIT=4

其二,-c 探测到 URI 不可达,直接拒绝添加:

$ zypper ar -c http://127.0.0.1:1/repo repo-bad
Adding repository 'repo-bad' [...error]
Problem transferring repository data from specified URI:
[|] Error trying to read from 'http://127.0.0.1:1/repo'
History:
 - Download (curl) error for 'http://127.0.0.1:1/repo/content':
   Error code: Connection failed Curl error (7)
   Error message: Failed to connect to 127.0.0.1 port 1 after 0 ms: Could not connect to server
Please check whether the specified URI is accessible.
#### EXIT=4

addrepo 还支持 -f(启用自动刷新)、-p(优先级)、-k/-K(rpm 缓存留存)、-g/-G(GPG 检查开关)等选项,完整清单见 zypper help addrepo。.repo 文件也能直接作为参数批量导入(见 4.2 踩坑实录)。

💡 说明: -c 只在建源时探测一次,-C/--no-check 则完全不探测。生产上建议养成 ar -c 习惯:把「URL 拼错」这类低级问题拦在添加阶段,而不是等 refresh 时才爆出一串 curl 错误。注意本地目录源添加后 URI 会显示为 dir:/srv/repo-local 形式(见 3.16)。

3.5 modifyrepo(mr)与 removerepo(rr)

实测禁用/启用/优先级/关闭自动刷新四连:

$ zypper mr -d repo-demo-nonoss
Repository 'repo-demo-nonoss' has been successfully disabled.

$ zypper mr -e repo-demo-nonoss
Repository 'repo-demo-nonoss' has been successfully enabled.

$ zypper mr -p 50 repo-demo-nonoss
Repository 'repo-demo-nonoss' priority has been set to 50.

$ zypper lr -p 复核后第 7 行:
7 | repo-demo-nonoss            | Leap 16.0 Demo Non-OSS    | Yes     | ( p) Yes  | No      |   50

删除软件源与「删除不存在的源」对照:

$ zypper rr repo-demo-nonoss
Removing repository 'Leap 16.0 Demo Non-OSS' [...........done]
Repository 'Leap 16.0 Demo Non-OSS' has been removed.

$ zypper removerepo nosuchrepo
Repository 'nosuchrepo' not found by alias, number or URI.
#### EXIT=0

💡 说明: 两个反直觉点。其一,rr 一个不存在的源退出码是 0 而非非零——脚本里判断「删除成功与否」不能只看退出码,要配合 lr 复核。其二,优先级数值越小越优先(默认 99),设置 50 后输出会从「priorities are without effect」变为「priorities in effect」,可据此确认优先级确实生效了。

3.6 search(se):查询软件包

默认按「子串匹配」搜包名,实测 zypper se tree(匹配出上百个带 tree 的包名,节选首尾):

$ zypper se tree
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...

S  | Name                             | Summary                                                                  | Type
---+----------------------------------+--------------------------------------------------------------------------+--------
   | budgie-wallstreet                | Wallstreet applet                                                        | package
   | cherrytree                       | A hierarchical note taking application                                   | package
   | erdtree                          | A multi-threaded file-tree visualizer and disk usage analyzer            | package
   | libostree                        | Git for operating system binaries                                        | package
   | perl-HTML-Tree                   | Build and Scan Parse-Trees of Html                                       | package
   | texlive-qtree                    | Draw tree structures                                                     | package
i+ | tree                             | File listing as a tree                                                   | package
   | tree-sitter                      | An incremental parsing system for programming tools                      | package
   | vim-plugin-NERDtree              | A tree explorer plugin for navigating the filesystem                     | package

(节选:仅保留首尾若干行,实际输出 160 行左右。i+ 表示已安装,+ 表示该包还系统推荐安装。)

-s/--details 把「每个仓库里每个版本」各打一行,版本对比一目了然(能看到 libtree-sitter0_26 同名包有 160000.2.1 与 160000.1.1 两个版本、maven-dependency-tree 有三个版本共存于源中):

$ zypper se -s tree
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...

S  | Name                             | Type    | Version                                    | Arch   | Repository
---+----------------------------------+---------+--------------------------------------------+--------+----------------
   | budgie-wallstreet                | package | 1.9.0-bp160.1.2                            | x86_64 | repo-oss (16.0)
   | cherrytree                       | package | 1.1.4+18-bp160.1.16                        | noarch | repo-oss (16.0)
   | libtree-sitter0_26               | package | 0.26.8-160000.2.1                          | x86_64 | repo-oss (16.0)
   | libtree-sitter0_26               | package | 0.26.8-160000.1.1                          | x86_64 | repo-oss (16.0)
   | maven-dependency-tree            | package | 3.3.0-160000.1.1                           | noarch | repo-oss (16.0)
   | maven-dependency-tree            | package | 3.2.1-160000.3.1                           | noarch | repo-oss (16.0)
i+ | tree                             | package | 2.2.1-160000.2.2                           | x86_64 | repo-oss (16.0)

(节选:仅保留代表性行。)

-x/--match-exact 精确匹配包名,只留 tree 本尊:

$ zypper se -x tree
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...

S  | Name | Summary                | Type
---+------+------------------------+--------
i+ | tree | File listing as a tree | package

-d/--search-descriptions 连摘要与描述一起搜。实测 zypper se -d tree 命中 511 行(| wc -l 计数),远多于按名匹配,适合「知道功能不知道包名」的场景。搜索还支持通配符(*、?)与正则(用 / 包裹),以及 --provides/--requires 等按依赖关系反查(见 3.18)。

💡 说明: se -s 是排障利器——「源里到底有几个版本、哪个仓库提供」一眼看穿;配合 -r <别名> 可只看某个源。要注意 zypper 的 -s 是 details 而不是 sort,与 apt/dnf 的直觉不同(apt list / dnf list 大致对应 se -s)。

3.7 info(if):查看包详情与依赖

$ zypper info tree
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...


Information for package tree:
-----------------------------
Repository     : repo-oss (16.0)
Name           : tree
Version        : 2.2.1-160000.2.2
Arch           : x86_64
Vendor         : SUSE LLC <https://www.suse.com/>
Installed Size : 148.8 KiB
Installed      : Yes
Status         : up-to-date
Source package : tree-2.2.1-160000.2.2.src
Upstream URL   : https://oldmanprogrammer.net/tar/tree/
Summary        : File listing as a tree
Description    :
    Tree is a recursive directory listing command that produces a depth
    indented listing of files, which is colorized ala dircolors if the
    LS_COLORS environment variable is set and output is to tty.

--requires 追加依赖清单(tree 只依赖 glibc):

$ zypper if --requires tree
(头部同上,省略)
Requires       : libc.so.6(GLIBC_2.38)(64bit)

-s 模糊匹配打印多个包详情,实测 zypper if -s libonig 打出 libonig5 全量信息(含支持字符编码列表)。info 同样支持 -t 类型化查询(pattern/product/patch),见 3.17。

💡 说明: info 的 Installed: Yes/No 与 Status: up-to-date 两行是确认「装没装、新不新」的最快途径;Installed Size 是预估磁盘占用,批量部署前用它估算容量比装完再 du 更省事。状态行 Status 可能出现 up-to-date(最新)、not installed(未装)、out-of-date(可升级)三种。

3.8 install(in):安装软件包

最常规安装(-y 免确认,输出里 Continue? ... (y): y 表示已自动应答):

$ zypper in -y tree
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following NEW package is going to be installed:
  tree

1 new package to install.

Package download size:    84.2 KiB

Package install size change:
              |     148.8 KiB  required by packages that will be installed
   148.8 KiB  |  -      0 B    released by packages that will be removed

Backend:  classic_rpmtrans
Continue? [y/n/v/...? shows all options] (y): y
Preloading Packages [..
Preloading: tree-2.2.1-160000.2.2.x86_64.rpm [done]
.done]
Retrieving: tree-2.2.1-160000.2.2.x86_64 (repo-oss (16.0)) (1/1),  84.2 KiB

Checking for file conflicts: [..done]
(1/1) Installing: tree-2.2.1-160000.2.2.x86_64 [..done]
Running post-transaction scripts [...done]

rpm 层验证安装结果(本文多个演示包都用这一手复核):

$ rpm -q tree
tree-2.2.1-160000.2.2.x86_64

$ tree --version
tree v2.2.1 (c) 1996 - 2024 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro

-d/--download-only 只下载不安装。实测下载 bc 后 rpm 查询仍显示未安装,rpm 文件落在缓存目录:

$ zypper in -d -y bc
(事务摘要同上,Backend 行变为:)
Backend:  classic_rpmtrans --download-only
Retrieving: bc-1.07.1-160000.2.2.x86_64 (repo-oss (16.0)) (1/1), 115.7 KiB
#### EXIT=0

$ rpm -q bc
package bc is not installed
#### EXIT=1

$ ls -R /var/cache/zypp/packages/
/var/cache/zypp/packages/openSUSE:repo-oss/%2E%2E/x86_64:
bc-1.07.1-160000.2.2.x86_64.rpm

再执行 zypper in -y bc 时会直接命中缓存(In cache bc-...rpm (1/1)),不再走网络。-f/--force 强制重装已安装的包:

$ zypper in -f -y tree
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...
Forcing installation of 'tree-2.2.1-160000.2.2.x86_64' from repository 'repo-oss (16.0)'.
Resolving package dependencies...

The following package is going to be reinstalled:
  tree

1 package to reinstall.
(后续流程同常规安装)

-D/--dry-run 只演不装,并附带一条真实的完整性提示:

$ zypper in -D -y zip
(事务摘要:1 new package to install,Backend: classic_rpmtrans --dry-run)
Checking for file conflicts: [...done]
Warning: 1 package had to be excluded from file conflicts check because it is not yet download.

    Note: Checking for file conflicts requires not installed packages to be downloaded in advance in
    order to access their file lists. See option '--download-in-advance / --dry-run --download-only'
    in the zypper manual page for details.
#### EXIT=0

$ rpm -q zip
package zip is not installed

依赖解析:装 jq 自动拉齐 libjq1、libonig5,下载/安装顺序由求解器给出:

$ zypper in -y jq
The following 3 NEW packages are going to be installed:
  jq libjq1 libonig5

3 new packages to install.
(Preloading 三包 → Retrieving (1/3)(2/3)(3/3) → Installing (1/3)(2/3)(3/3))

不存在的包名,报错与退出码:

$ zypper in -y nosuchpkg-xyz
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...
'nosuchpkg-xyz' not found in package names. Trying capabilities.
No provider of 'nosuchpkg-xyz' found.
#### EXIT=104

install 的关键命令选项(来自实测帮助):-t 指定类型(package/patch/pattern/product)、-n 按纯名而非能力匹配、--from 指定从哪个源选包、-r 限定源、-y/--no-confirm 免确认(帮助原文注明这是全局 --non-interactive 的别名)、--download <MODE>(only/in-advance/in-heaps/as-needed 四种模式)、--recommends/--no-recommends 控制推荐包。

💡 说明: 三条实测得出的经验。其一,-d 下载产物落在 /var/cache/zypp/packages/<源别名>/... 下,目录名里的 %2E%2E 是 URL 转义后的「..」,属正常现象;提前把 rpm 下到缓存再做 in 可实现弱网机房安装。其二,-D 单独使用时文件冲突检查不完整(如上 Warning),要完整的冲突检查用 -D -d 连用(实测见 3.18 的 zip 复测)。其三,对已安装包重复 in 不会报错,只会提示 'bc' is already installed. 与 No update candidate ...,随后 Nothing to do.,退出码 0,脚本可放心幂等重入。

3.9 remove(rm):卸载软件包

$ zypper rm -y sl
Reading installed packages...
Resolving package dependencies...

The following package is going to be REMOVED:
  sl

1 package to remove.

Package install size change:
              |         0 B    required by packages that will be installed
   -35.7 KiB  |  -   35.7 KiB  released by packages that will be removed

Backend:  classic_rpmtrans
Continue? [y/n/v/...? shows all options] (y): y
(1/1) Removing: sl-5.05-bp160.1.3.x86_64 [..done]
Running post-transaction scripts [...done]

-u/--clean-deps 连不再被依赖的运行库一起清掉,jq 三件套一次清空:

$ zypper rm --clean-deps -y jq
Reading installed packages...
Resolving package dependencies...

The following 3 packages are going to be REMOVED:
  jq libjq1 libonig5

3 packages to remove.
((1/3)(2/3)(3/3) 依次 Removing)
#### EXIT=0

$ rpm -q jq libonig5
package jq is not installed
package libonig5 is not installed
#### EXIT=2

卸载 dry-run 与「卸载不存在的包」对照:

$ zypper rm -D -y tree
(1 package to remove,Backend: classic_rpmtrans --dry-run)
$ rpm -q tree
tree-2.2.1-160000.2.2.x86_64

$ zypper rm -y nosuchpkg-xyz
'nosuchpkg-xyz' not found in package names. Trying capabilities.
No provider of 'nosuchpkg-xyz' found.
Resolving package dependencies...
Nothing to do.
#### EXIT=104

💡 说明: rm 默认只删指定包、保留依赖(反向保护);-u 才顺带清依赖。与 -u 相对的是 -U/--no-clean-deps 显式禁止。此外 remove 支持 -t pattern 卸载整个 pattern,但 Leap 16 的 minimal_base 属于产品级 pattern,强行卸载会连带动到系统基础组件,不建议在生产机上尝试。

3.10 update(up)与 list-updates(lu):包级更新

更新流程是「先 lu 看清单,再 up 执行」。实测初始状态有 2 个可升级包:

$ zypper lu
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...
S  | Repository      | Name                       | Current Version    | Available Version       | Arch
---+-----------------+----------------------------+--------------------+-------------------------+-------
v  | repo-oss (16.0) | patterns-base-fips         | 20241218-lp160.5.1 | 20241218+leap-lp160.1.1 | x86_64
v  | repo-oss (16.0) | patterns-base-minimal_base | 20241218-lp160.5.1 | 20241218+leap-lp160.1.1 | x86_64

up -D -y 干跑给出完整事务计划——含 2 包升级、12 个新依赖(libcurl4 全家桶)、1 个被替换移除的 libcurl-mini4:

$ zypper up -D -y
The following 2 packages are going to be upgraded:
  patterns-base-fips patterns-base-minimal_base

The following 2 patterns are going to be upgraded:
  fips minimal_base

The following 12 NEW packages are going to be installed:
  krb5 libbrotlicommon1 libbrotlidec1 libcom_err2 libcurl4 libkeyutils1 libldap-2 libldap-data libsasl2-3 libssh-config libssh4 libverto1

The following package is going to be REMOVED:
  libcurl-mini4

2 packages to upgrade, 12 new, 1 to remove.

Package download size:     2.4 MiB
Backend:  classic_rpmtrans --dry-run

(注意这里 krb5 等包被列为 NEW,是因为先一步 up 之前 lsof 尚未安装;真实执行时已装过的依赖会自动从清单里剔除。)

真实执行(同一台机,先装了 lsof,新依赖剩 8 个):

$ zypper up -y
The following 2 packages are going to be upgraded:
  patterns-base-fips patterns-base-minimal_base
The following 8 NEW packages are going to be installed:
  libbrotlicommon1 libbrotlidec1 libcurl4 libldap-2 libldap-data libsasl2-3 libssh-config libssh4
The following package is going to be REMOVED:
  libcurl-mini4

2 packages to upgrade, 8 new, 1 to remove.
(Preloading/Retrieving 10 个 rpm → 逐个 Installing → Running post-transaction scripts)
#### EXIT=0

$ zypper lu
No updates found.
#### EXIT=0

💡 说明: up 只在「同源同 vendor 同架构」前提下做保守升级;跨 vendor 换包(如上例 libcurl-mini4 → libcurl4)会被求解器以依赖调整的形式完成并在摘要里明示。看到 REMOVED 行别慌,先读 The following package is going to be REMOVED 前后的上下文确认是被新包替代而非误删。--best-effort、-r 限定源、--skip-interactive 是 up 的常用变体。

3.11 patch、list-patches(lp)与 patch-check(pchk):补丁管理

补丁(patch)是 openSUSE 语义下的「一组有安全/修复标记的包集合」。实测待打补丁状态:

$ zypper lp
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...

Repository      | Name                    | Category    | Severity | Interactive | Status | Since | Summary
----------------+-------------------------+-------------+----------+-------------+--------+-------+-------------------------------------
repo-oss (16.0) | openSUSE-Leap-16.0-500  | recommended | moderate | ---         | needed | -     | Recommended update for patterns-base
repo-oss (16.0) | openSUSE-Leap-16.0-1126 | recommended | moderate | ---         | needed | -     | Recommended update for patterns-base

Found 2 applicable patches:
2 patches needed (0 security patches)

pchk 在有待打补丁时退出码为 100(这是脚本判断的关键信号):

$ zypper pchk
Found 2 applicable patches:
Category    | Patches
------------+--------
recommended | 2

2 patches needed (0 security patches)
#### EXIT=100

patch --category security 干跑,过滤非安全类补丁后无事可做(本机待打补丁恰好全是 recommended 类):

$ zypper patch -D --category security
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...
Patch 'openSUSE-Leap-16.0-1126-1' is not in the specified category.
Patch 'openSUSE-Leap-16.0-500-1' is not in the specified category.
Resolving package dependencies...
Nothing to do.
#### EXIT=0

执行 up -y 把两个 recommended 补丁涉及的包升到修复版后,补丁自动转为已满足状态——patch -y 再跑就只剩 Nothing to do.,pchk 变为 0 patches needed (0 security patches) 且退出码 0(完整闭环见 3.10、3.17 与 4.1)。patch-info <补丁名> 查询单个补丁详情,查不存在的补丁退出码 104。Leap 16 默认源同步携带全部历史补丁元数据,lp --all 会列出数百条 not needed/applied 状态的历史补丁(节选首部):

$ zypper lp --all
Repository      | Name                     | Category    | Severity  | Interactive | Status     | Since | Summary
----------------+--------------------------+-------------+-----------+-------------+------------+-------+------------------------------------------------------------------
repo-oss (16.0) | openSUSE-Leap-16.0-2     | security    | moderate  | ---         | not needed | -     | Recommended update of flake-pilot
repo-oss (16.0) | openSUSE-Leap-16.0-3     | recommended | moderate  | ---         | not needed | -     | Recommended update of python-instance-billing-flavor-check
repo-oss (16.0) | openSUSE-Leap-16.0-4     | recommended | moderate  | ---         | not needed | -     | Recommended update of cloud-regionsrv-client
repo-oss (16.0) | openSUSE-Leap-16.0-5     | recommended | moderate  | ---         | not needed | -     | Recommended update of aws-cli-cmd, az-cli-cmd
repo-oss (16.0) | openSUSE-Leap-16.0-6     | recommended | important | ---         | not needed | -     | Recommended update for gdm
repo-oss (16.0) | openSUSE-Leap-16.0-7     | recommended | moderate  | ---         | not needed | -     | Recommended update for busybox
repo-oss (16.0) | openSUSE-Leap-16.0-8     | recommended | critical  | ---         | not needed | -     | Recommended update for autofs

💡 说明: patch 与 up 的分工——patch 只装「补丁语义」内需要的包(默认跳过 optional 与 interactive),up 则把所有有新版本的包都升上去;安全基线场景用 patch --category security --severity important 做精准最小化处置,全面升级再用 up。另外 Interactive 列出现 reboot 的补丁装完要用 zypper needs-rebooting 与 zypper ps 复核(见 3.18)。

3.12 dist-upgrade(dup)概念对照

dup 是「整系统与软件源当前状态对齐」的全量升级:允许降级、允许换 vendor、允许增删包,目标是把整个安装面拉到与源一致的最新状态。实测 zypper help dist-upgrade 的关键差异选项:--from <ALIAS|#|URI> 限定只对指定源做对齐、--remove-orphaned 清除孤儿包。Leap 15→16 这类大版本迁移的标准做法也是 zypper dup(配合新源的 repos 定义)。

维度uppatchdup
范围所有可升级包仅补丁语义内的包整个系统与源对齐
降级默认不允许不涉及允许(对齐所需时)
换 vendor默认不允许不涉及允许
增删包依赖调整导致依赖调整导致常态(含孤儿清理)
典型场景日常升级安全基线版本迁移、换源后收口

💡 说明: dup 动作重、影响面大,本文实测环境选择不执行真实 dup(避免把最小化环境引到与演示无关的状态),但这不影响命令语义说明——生产执行前务必先 dup -D 干跑并通读 REMOVED/DOWNGRADED 清单。与 apt 系 apt full-upgrade、dnf 系 dnf distro-sync 的心智模型最接近。

3.13 clean(cc):清理缓存

缓存分三层:包缓存(下载的 rpm)、原始元数据缓存(raw)、构建后的索引缓存(solv)。实测大小与两级清理:

$ du -sh /var/cache/zypp/*
24K     /var/cache/zypp/packages
34M     /var/cache/zypp/raw
44M     /var/cache/zypp/solv

$ zypper clean
All repositories have been cleaned up.

$ du -sh /var/cache/zypp/*
4.0K    /var/cache/zypp/packages
34M     /var/cache/zypp/raw
44M     /var/cache/zypp/solv

$ zypper clean -a
All repositories have been cleaned up.

$ du -sh /var/cache/zypp/*
4.0K    /var/cache/zypp/packages
4.0K    /var/cache/zypp/raw
4.0K    /var/cache/zypp/solv

clean 的选项矩阵:默认只清包缓存;-m/--metadata 清索引缓存;-M/--raw-metadata 清原始元数据;-a/--all 全清;-r <源> 只清指定源。实测 zypper clean -a 后第一次 install 会自动重建元数据(输出重新出现 Retrieving repository ... metadata 段,见 3.14)。

💡 说明: 磁盘紧张时优先 zypper clean -a,一次性回收实测约 78 MiB(34M raw + 44M solv + 包缓存);但元数据清掉后下一次查询要重建索引(几十秒),定时任务建议把 clean 放在夜间低峰。若希望「安装后自动留存 rpm 做离线备份」,方向是开 keep-packages(mr -k,见 4.5),而不是不清缓存。

3.14 verify(ve):依赖完整性校验与修复

verify 检查全系统依赖一致性并给出修复事务。实测人为制造一次损坏(rpm 层强拆 jq 依赖的 libonig5),再走完「发现 → 报告 → 修复 → 复核」闭环:

$ rpm -e --nodeps libonig5
(无输出,退出码 0)

$ echo '{"a":1}' | jq .a
jq: error while loading shared libraries: libonig.so.5: cannot open shared object file: No such file or directory
#### EXIT=127

$ zypper ve
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...

The following NEW package is going to be installed:
  libonig5

1 new package to install.
(大小摘要)
Some of the dependencies of installed packages are broken. In order to fix these dependencies, the following actions need to be taken:

Backend:  classic_rpmtrans --dry-run
Continue? [y/n/v/...? shows all options] (y): y
#### EXIT=0

zypper -n ve 采用默认答案自动执行修复事务,随后运行与复查全部恢复:

$ zypper -n ve
Some of the dependencies of installed packages are broken. In order to fix these dependencies, the following actions need to be taken:
(同上摘要,Backend: classic_rpmtrans,随后真实安装 libonig5)
(1/1) Installing: libonig5-6.9.8-160000.2.2.x86_64 [..done]
#### EXIT=0

$ echo '{"a":1}' | jq .a
1
#### EXIT=0

$ zypper ve -D -y
Dependencies of all installed packages are satisfied.
#### EXIT=0

💡 说明: 健康系统的 verify 命中「Dependencies of all installed packages are satisfied.」一行即通过;一旦出现 Some of the dependencies ... are broken,事务摘要就是要执行的最小修复集。ve -D -y 干跑、-n ve 修复、再 ve -D -y 复核,这三步可写进例行巡检脚本。verify 与 rpm -Va 互补:前者管依赖图、后者管文件指纹。

3.15 全局选项实测:-q、-t、-x、-v、-n 与 zypper shell

-q 安静模式:只抑制过程行,结果表格照常输出(与不带 -q 的输出逐行对比,Refreshing service/Loading repository data/Reading installed packages 三行消失):

$ zypper -q se tree

S  | Name                             | Summary                                  | Type
---+----------------------------------+------------------------------------------+--------
   | budgie-wallstreet                | Wallstreet applet                        | package
i+ | tree                             | File listing as a tree                   | package

-t terse 机器友好输出(无更新时输出极简,适合脚本直接判断):

$ zypper -t lu
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...
No updates found.

-x XML 输出(结构化机器消费,监控与 CI 场景直接解析):

$ zypper -x se tree
<?xml version='1.0'?>
<stream>
<message type="info">Refreshing service &apos;openSUSE&apos;.</message>
<message type="info">Loading repository data...</message>
<message type="info">Reading installed packages...</message>

<search-result version="0.0">
<solvable-list>
<solvable status="not-installed" name="budgie-wallstreet" summary="Wallstreet applet" kind="package"/>
<solvable status="installed" name="tree" summary="File listing as a tree" kind="package"/>
</solvable-list>
</search-result>
</stream>

$ zypper -x lu
<?xml version='1.0'?>
<stream>
<message type="info">Refreshing service &apos;openSUSE&apos;.</message>
<update-status version="0.6">
<update-list>
</update-list>
</update-status>
</stream>

-v 详细模式(打印检索细节与速度):

$ zypper -v ref 3
Verbosity: 2
Non-option program arguments: '3'
Initializing Target
Refreshing service 'openSUSE'.
Specified repositories: openSUSE:repo-openh264
Checking whether to refresh metadata for repo-openh264 (16.0)
Retrieving: repomd.xml [..done (2.9 KiB/s)]
Repository 'repo-openh264 (16.0)' is up to date.
Specified repositories have been refreshed.

-n 全局免交互:不给 -y 也能一路执行到装完(提示行显示自动应答 Continue? ... (y): y):

$ zypper -n in jq
(事务摘要同 3.8,(1/3)(2/3)(3/3) 安装完成)
#### EXIT=0

zypper shell 批量执行:一次会话连发多条命令,免去重复加载元数据:

$ printf 'se -x tree\nquit\n' | zypper shell
zypper(0)> se -x tree
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...

S  | Name | Summary                | Type
---+------+------------------------+--------
i+ | tree | File listing as a tree | package
zypper(0)> quit
#### EXIT=0

💡 说明: -y 与 -n 的实测差异——-y 是 install/remove/patch/up 等命令自带的「免确认」,-n 是全局「所有提问都用默认答案」(包括 GPG 未签名确认、密钥导入确认等所有交互点)。脚本里面对「可能弹任何提示」的 zypper 调用,-n 才是保险的;但注意 -n 在未签名源刷新时默认答案是 no,会直接中止(见 3.16 实测),此时要么 --no-gpg-checks、要么 --gpg-auto-import-keys。

3.16 GPG 签名信任与 --no-gpg-checks:本地软件源实战

用 createrepo_c 在本机搭一个无签名源,完整走一遍签名信任流程。准备:

$ zypper download tree
Retrieving: tree-2.2.1-160000.2.2.x86_64 (repo-oss (16.0)) (1/1),  84.2 KiB

$ mkdir -p /srv/repo-local
$ cp /var/cache/zypp/packages/openSUSE:repo-oss/%2E%2E/x86_64/tree-2.2.1-160000.2.2.x86_64.rpm /srv/repo-local/
$ createrepo_c /srv/repo-local
Directory walk started
Directory walk done - 1 packages
Temporary output repo path: /srv/repo-local/.repodata/
Pool started (with 5 workers)
Pool finished

添加并首次刷新——未签名警告与「非交互 EOF 中止」一并出现(报错原文完整保留):

$ zypper ar /srv/repo-local repo-local
Adding repository 'repo-local' [.....done]
Repository 'repo-local' successfully added

URI         : dir:/srv/repo-local
Enabled     : Yes
GPG Check   : Yes
Autorefresh : No

$ zypper ref repo-local
Refreshing service 'openSUSE'.
Retrieving repository 'repo-local' metadata [.
Looking for gpg keys in repository repo-local.
  gpgkey=dir:/srv/repo-local/repodata/repomd.xml.key
Warning: File 'repomd.xml' from repository 'repo-local' is unsigned.

    Note: Signing data enables the recipient to verify that no modifications occurred after the data
    were signed. Accepting data with no, wrong or unknown signature can lead to a corrupted system
    and in extreme cases even to a system compromise.

    Note: File 'repomd.xml' is the repositories master index file. It ensures the integrity of the
    whole repo.

    Warning: We can't verify that no one meddled with this file, so it might not be trustworthy
    anymore! You should not continue unless you know it's safe.

File 'repomd.xml' from repository 'repo-local' is unsigned.
Continue? [yes/no] (no): Cannot read input: bad stream or EOF.
If you run zypper without a terminal, use '--non-interactive' global
option to make zypper use default answers to prompts.
error]
Error retrieving metadata for 'repo-local':
Cannot read input. Bad stream or EOF.
Skipping repository 'repo-local' because of the above error.
Could not refresh the repositories because of errors.
#### EXIT=4

--no-gpg-checks 全局选项放行后,刷新与从本地源强制重装均正常:

$ zypper --no-gpg-checks ref repo-local
Refreshing service 'openSUSE'.
Retrieving repository 'repo-local' metadata [.
Looking for gpg keys in repository repo-local.
  gpgkey=dir:/srv/repo-local/repodata/repomd.xml.key
done]
Building repository 'repo-local' cache [....done]
Specified repositories have been refreshed.

$ zypper --no-gpg-checks in -y -f -r repo-local tree
(摘要:1 package to reinstall)
Retrieving: tree-2.2.1-160000.2.2.x86_64 (repo-local) (1/1),  84.2 KiB
(1/1) Installing: tree-2.2.1-160000.2.2.x86_64 [..done]
#### EXIT=0

落盘的源定义文件(普通源直接写在 /etc/zypp/repos.d/ 下):

$ cat /etc/zypp/repos.d/repo-local.repo
[repo-local]
enabled=1
autorefresh=0
baseurl=dir:/srv/repo-local

💡 说明: 三层处置策略按信任等级递进——①临时一次性放行:命令行加全局 --no-gpg-checks;②源级放行:mr --gpgcheck-allow-unsigned-repo 或建源时 ar --gpgcheck-allow-unsigned-repo;③有签名密钥但首次遇到:--gpg-auto-import-keys 自动信任导入。生产环境永远不要对公网源用 ①②,它们只适合内网自建源。另注意 -r repo-local 限定了安装动作只从这个源选包,重装结果摘要里 Retrieving 行的来源明确显示 (repo-local)。

3.17 包类型语义:package、patch、pattern、product

zypper 的软件对象有四种类型,-t 参数贯穿 search/info/install/remove。实测:

pattern(软件包集合/模式),se -t pattern 列出全部(节选首部,共 70 余个):

$ zypper se -t pattern
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...

S  | Name            | Summary                                                             | Type
---+-----------------+---------------------------------------------------------------------+--------
   | 32bit           | 32-Bit Runtime Environment                                          | pattern
   | apparmor        | AppArmor                                                            | pattern
   | base            | Base System                                                         | pattern
   | basic_desktop   | A basic desktop (based on IceWM)                                    | pattern
   | books           | Documentation                                                       | pattern
   | cockpit         | Pattern for Cockpit, a web based remote system management interface | pattern
   | console         | Console Tools                                                       | pattern
i  | fips            | FIPS 140-3 specific packages                                        | pattern
i  | minimal_base    | Minimal Appliance Base                                              | pattern

(节选:仅保留首部与两个已安装 pattern,其余包括 devel_basis、enhanced_base、lamp_server、x11、xfce 等。)

pattern 详情直接列出成员清单与推荐依赖(i+ 表示成员已装):

$ zypper if -t pattern enhanced_base
Information for pattern enhanced_base:
--------------------------------------
Repository      : repo-oss (16.0)
Name            : enhanced_base
Version         : 20241218+leap-lp160.1.1
Arch            : x86_64
Vendor          : openSUSE
Buddy Package   : patterns-base-enhanced_base-20241218+leap-lp160.1.1.x86_64
Installed       : No
Visible to User : Yes
Summary         : Enhanced Base System
Contents        :
    S  | Name                  | Type     | Dependency
    ---+-----------------------+----------+------------
       | pattern:base          | pattern  | Required
       | openssh               | package  | Required
       | pattern:sw_management | pattern  | Recommended
       | acl                   | package  | Recommended
    i+ | curl                  | package  | Recommended

(节选:成员表仅保留代表性行。)

pattern 安装 dry-run 实测(enhanced_base 连同 base pattern 一共要动 51 个包、27.7 MiB 下载、79.1 MiB 磁盘):

$ zypper in -D -y -t pattern enhanced_base
The following 51 NEW packages are going to be installed:
  alts chrony chrony-pool-openSUSE coreutils-systemd crypto-policies-scripts dbus-1 dbus-1-common dbus-1-tools dbus-broker dbus-broker-block-restart diffutils findutils kbd libalternatives1 libcbor0_11 libdbus-1-3 libedit0 libexpat1 libfido2-1 libgnutls30 libhidapi-hidraw0 libhogweed6 libkbdfile1 libkeymap1 libkfont0 libleancrypto1 libmpdec4 libnettle8 libpkgconf5 libpython3_13-1_0 libseccomp2 libwtmpdb0 openssh openssh-clients openssh-common openssh-server pam-config pam-extra patterns-base-base patterns-base-enhanced_base pkgconf pkgconf-m4 pkgconf-pkg-config python3-base python313-base systemd systemd-default-settings systemd-default-settings-branding-openSUSE systemd-presets-branding-openSUSE systemd-presets-common-SUSE wtmpdb

The following 2 NEW patterns are going to be installed:
  base enhanced_base

51 new packages to install.

Package download size:    27.7 MiB
Backend:  classic_rpmtrans --dry-run

product(产品),本机安装的就是 Leap 产品:

$ zypper se -t product
S  | Name | Summary            | Type
---+------+--------------------+--------
i+ | Leap | openSUSE Leap 16.0 | product

$ zypper if -t product Leap
Information for product Leap:
-----------------------------
Repository          : repo-oss (16.0)
Name                : Leap
Version             : 16.0-1
Arch                : x86_64
Vendor              : openSUSE
End of Support      : 2027-11-30
Is Base             : Yes
Installed           : Yes
Status              : up-to-date
CPE Name            : cpe:2.3:o:opensuse:leap:16.0:*:*:*:*:*:*:*
Short Name          : Leap
Summary             : openSUSE Leap 16.0

patch(补丁) 按名安装的 dry-run(补丁语义同样支持 -t patch):

$ zypper in -D -y -t patch openSUSE-Leap-16.0-500
'patch:openSUSE-Leap-16.0-500' is already installed.
Resolving package dependencies...
Nothing to do.
#### EXIT=0

显式类型修饰符。-t package 形式正常工作(zypper in -y -t package zip 成功安装后随即 zypper rm -y zip 回收);但网传的「冒号类型修饰符」写法 zypper in tree:package 在 zypper 1.14.101 实测不支持:

$ zypper in tree:package
Refreshing service 'openSUSE'.
Loading repository data...
Reading installed packages...
'tree:package' not found in package names. Trying capabilities.
No provider of 'tree:package' found.
Resolving package dependencies...
Nothing to do.
#### EXIT=104

💡 说明: 「包名:类型 冒号修饰符」在一些资料里被当作 zypper 语法传播,实测 zypper 1.14.101 并不认识它(报 not found,退出码 104)——正确写法只有 -t <TYPE>。另外 in -t patch <补丁名> 在补丁已被 up 满足时会显示 'patch:xxx' is already installed.,这个 patch: 前缀是 zypper 自己的展示格式而非用户可输入的语法,别被输出带偏。

3.18 其他实用子命令速览

download:把指定包的 rpm 下到包缓存(不安装),本地源构建的前置动作(见 3.16):

$ zypper download tree
Retrieving: tree-2.2.1-160000.2.2.x86_64 (repo-oss (16.0)) (1/1),  84.2 KiB

needs-rebooting 与 ps:升级后重启判定与「进程占用已删除库」检查。ps 依赖 lsof,最小化环境缺它时直接报错(实测原文):

$ zypper ps
Check failed:
Please install package 'lsof' first.
#### EXIT=4

$ zypper in -y lsof
(The following 7 NEW packages are going to be installed: krb5 libcom_err2 libkeyutils1 libtirpc-netconfig libtirpc3 libverto1 lsof)
$ zypper ps
No processes using deleted files found.

No core libraries or services have been updated since the last system boot.
Reboot is probably not necessary.
#### EXIT=0

$ zypper needs-rebooting
No core libraries or services have been updated since the last system boot.
Reboot is probably not necessary.
#### EXIT=0

vcmp:版本号比较工具(输出人类可读,退出码表意):

$ zypper vcmp 1.2.3 1.10.0
1.2.3 is older than 1.10.0
#### EXIT=12

targetos / system-architecture / licenses:

$ zypper targetos
/etc/products.d/baseproduct does not define XPath:/product/register/target.
Distribution Label: openSUSE Leap 16.0

$ zypper system-architecture
x86_64_v3

$ zypper licenses
Leap-release-16.0+leap-lp160.264.1 (package)
License: MIT
-
aaa_base-84.87+git20260610.3b5a868c-160000.1.1 (package)
License: GPL-2.0-or-later
-
bash-5.2.37-160000.2.2 (package)
License: GPL-3.0-or-later
-

(licenses 输出节选:全系统包的许可报告较长。)

--dry-run + --download-only 组合:干跑同时完成「完整文件冲突检查」与「rpm 预下载」,消除 3.8 中那条 Warning:

$ zypper in -D -d -y zip
Backend:  classic_rpmtrans --dry-run --download-only
Preloading: zip-3.0-160000.2.2.x86_64.rpm [done]
Checking for file conflicts: [..done]
#### EXIT=0

$ rpm -q zip
package zip is not installed

能力反查:se --provides 找「谁提供某个 so/能力」,wp 是被弃用的旧入口:

$ zypper se --provides 'libonig.so.5()(64bit)'
S  | Name     | Summary                                                | Type
---+----------+--------------------------------------------------------+--------
   | libonig5 | Regex Library Supporting Different Character Encodings | package

$ zypper wp tree
Command 'what-provides' is replaced by 'search --provides --match-exact'.
See 'help search' for all available options.
(随后输出等价结果)

💡 说明: 排障组合拳——报错日志里出现 cannot open shared object file: libxxx.so.N 时,先 se --provides 'libxxx.so.N()(64bit)' 找到提供者包,再 in -y 提供者包 补齐(完整案例见 4.3)。system-architecture 输出 x86_64_v3 说明本环境支持 v3 微架构,源里带 -x86-64-v3 后缀的优化包即为此准备。

3.19 报错行为与退出码实测

把本文踩到的退出码汇总成表(全部为实测值):

退出码触发场景(实测)含义
0成功安装/卸载/查询/刷新;rr 不存在的源;patch -y 无事可做正常结束(注意 rr 的例外,见 3.5)
3zypper ref repo-oss(短别名);ref nosuchrepo指定的源不存在(未按别名/编号/URI 找到)
4刷新失败(repo-bogus);ar -c 探测失败;重复别名 ar;从 .repo 文件部分导入;zypper ps 缺 lsof操作执行中出错(网络/校验/参数对象问题)
100zypper pchk(有 2 个待打补丁)检查类命令的「有结果待处理」信号
104in/rm 不存在的包名;patch-info 查无此补丁;in tree:package指定的能力/包/补丁找不到
127缺库的 jq;脚本里的 which/find/sl命令本身或动态库缺失(bash 层报错,非 zypper)
12zypper vcmp 1.2.3 1.10.0vcmp 专用:第一个版本旧于第二个

zypper help <COMMAND> 是一切详情入口;zypper shell 内可连续执行省去重复元数据加载。

💡 说明: 脚本判断「有没有更新/补丁」用退出码最可靠——zypper pchk 退出 100 表示有待打补丁、0 表示干净;zypper lu 有更新时输出表格、退出码恒 0,需解析输出或改用 lu -t 的紧凑格式。把 3/4/100/104 四个码写进巡检脚本的分支判断即可覆盖绝大多数异常。

3.20 拓展:主流包管理器常用操作对照表

面向多发行版运维的对照速查(zypper 列为本文实测结论;其余列按各发行版当前稳定版的常用用法整理,供迁移时参考):

操作zypper (openSUSE)apt (Debian/Ubuntu)yum (EL 7)dnf (EL 8+/Fedora)pacman (Arch)apk (Alpine)emerge (Gentoo)xbps (Void)
查看软件源列表zypper lr -dcat /etc/apt/sources.list 及 sources.list.d/yum repolistdnf repolist编辑 /etc/pacman.d/ 配置cat /etc/apk/repositoriescat /etc/portage/repos.conf/xbps-query -L
刷新元数据zypper refreshapt updateyum makecachednf makecachepacman -Syapk updateemerge --syncxbps-install -S
安装包zypper in treeapt install treeyum install treednf install treepacman -S treeapk add treeemerge treexbps-install tree
免确认安装zypper in -y tree(或全局 -n)apt install -y treeyum install -y treednf install -y treepacman -S --noconfirm tree默认不询问emerge --ask=n treexbps-install -y tree
卸载包zypper rm treeapt remove treeyum remove treednf remove treepacman -R treeapk del treeemerge -C treexbps-remove tree
卸载并清无用依赖zypper rm -u tree(--clean-deps)apt autoremoveyum autoremovednf autoremovepacman -Rs tree无专用命令(按 world 管理)emerge --depcleanxbps-remove -O
搜索包zypper se treeapt search treeyum search treednf search treepacman -Ss treeapk search treeemerge -s treexbps-query -Rs tree
包详情zypper info treeapt show treeyum info treednf info treepacman -Si/-Qi treeapk info treeemerge --info treexbps-query -R tree
列出可更新zypper luapt list --upgradableyum check-updatednf check-updatepacman -Quapk version -lemerge -upDN @worldxbps-install -un
执行包级更新zypper upapt upgradeyum updatednf upgradepacman -Suapk upgradeemerge -uDN @worldxbps-install -u
全量对齐升级zypper dupapt full-upgrade无对应(大版本走升级流程)dnf distro-syncpacman -Syuapk upgradeemerge -uDN @worldxbps-install -Su
安全补丁过滤zypper patch --category security无原生过滤yum update --securitydnf update --security无无glsa-check -f all无
修复依赖完整性zypper verifyapt --fix-broken installyum distro-syncdnf distro-sync无(极少损坏)apk fixemerge -uDN @worldxbps-install -Su
清理缓存zypper clean -aapt cleanyum clean alldnf clean allpacman -Scapk cache cleaneclean-dist手工清 /var/cache/xbps/
锁定包版本zypper addlock treeapt-mark hold treeyum versionlockdnf versionlockIgnorePkg 配置项无package.mask 配置无原生 hold

关键差异解读:

  • 确认机制:zypper 的 -y 是命令选项(帮助原文注明等价于全局 --non-interactive),与 apt/dnf 的 -y 同名同义;pacman 用 --noconfirm;apk 本就不询问。
  • 依赖清理思路:zypper rm -u 随卸载顺带清依赖;dnf autoremove/xbps-remove -O 是事后清理孤儿;pacman -Rs 与 zypper 语义最近。
  • 补丁语义:zypper patch 与 dnf update --security 都有安全过滤,但 zypper 的 patch 是一等公民(有 lp/pchk/patch-info 全套支撑),且 Leap 16 的补丁元数据直接随 repo-oss 分发。
  • dup 的危险性分级:dup 允许降级与换 vendor,在「混入第三方源」的机器上比 up 激进得多;dnf 对应动作是 distro-sync,apt 是 full-upgrade,执行前都应干跑审阅。

四、实战示例

4.1 场景一:新接管一台 Leap 16 服务器的例行巡检与更新

一条龙命令序列(每步都来自 3.x 实测,可直接组合进巡检脚本):

zypper ref -s                      # 服务+全部源刷新
zypper lu                          # 看包更新清单
zypper lp                          # 看补丁清单(含安全补丁计数)
zypper pchk; echo "pchk_exit=$?"   # 退出码 100=有待打补丁
zypper up -y                       # 执行包级更新
zypper pchk                        # 复查补丁是否清零
zypper needs-rebooting             # 是否需要重启
zypper ps                          # 是否有进程占用被删除的库

实测执行链路:初始 pchk 退出码 100(2 个 recommended 补丁)→ up -y 完成 2 包升级 + 8 新增 + 1 替换移除(libcurl-mini4 → libcurl4)→ lu 变为 No updates found. → pchk 变为 0 patches needed (0 security patches) 且退出码 0 → needs-rebooting 与 ps 均给出 Reboot is probably not necessary.。若 ps 报 Please install package 'lsof' first.,先 zypper in -y lsof 再重试(实测原文见 3.18)。

💡 说明: 巡检脚本建议把 zypper ref -s、pchk、ps 三个点作为告警源:ref 失败(退出码 4)意味着源不可达或 URI 失效,可能连安全补丁都拿不到;pchk 退出码 100 常态提醒;ps 非空意味着升级后仍有进程用旧库,需要择机重启对应服务而不是盲目 reboot 整机。

4.2 场景二:软件源清单备份与迁移(含踩坑实录)

备份(见 3.3 的导出实测):zypper lr --export /root/demo-repos-backup.repo。恢复时直接把导出文件喂回 addrepo,实测发生了什么——服务托管条目全部报「已存在」,手工添加的条目成功导入并带回优先级设置:

$ zypper ar /root/demo-repos-backup.repo
Adding repository 'repo-non-oss (16.0)' [...error]
Repository named 'openSUSE:repo-non-oss' already exists. Please use another alias.
(5 个 openSUSE: 前缀的服务源同样报 already exists)
Adding repository 'Leap 16.0 Demo Non-OSS' [.....done]
Repository 'Leap 16.0 Demo Non-OSS' successfully added

URI         : http://cdn.opensuse.org/distribution/leap/16.0/repo/non-oss/x86_64
Enabled     : Yes
GPG Check   : Yes
Autorefresh : No
Priority    : 50 (raised priority)

Repository priorities in effect: (See 'zypper lr -P' for details)
      50 (raised priority)  :  1 repository
      99 (default priority) :  2 repositories
#### EXIT=4

注意即使导入了部分条目,退出码仍是 4(有报错项),脚本要用输出内容而非仅退出码判断成败;清理用 zypper rr repo-demo-nonoss(实测删除成功,退出码 0)。

💡 说明: 这个「半成功」行为是设计的:服务托管源的真相在服务定义里(/etc/zypp/services.d/),换机器后服务一刷新就会重建,不需要从 .repo 文件导入;.repo 导出文件真正承载的是手工添加源(别名、优先级、autorefresh 等属性)。迁移生产机时,正确顺序是:新机装好 opensuse-repos 服务定义 → 手工源逐条 ar -c(探测后再加)→ lr -d 与旧机 diff。

4.3 场景三:依赖损坏排障实录(jq 缺 libonig.so.5)

现象:运行 jq 报动态库缺失(3.14 实测现场):jq: error while loading shared libraries: libonig.so.5: cannot open shared object file: No such file or directory。三步定位修复:

zypper se --provides 'libonig.so.5()(64bit)'   # 谁提供这个 so?→ libonig5
zypper ve -D -y                                 # 哪些包坏了?→ 需要补装 libonig5
zypper -n ve                                    # 执行最小修复事务

实测修复完成后 echo '{"a":1}' | jq .a 输出 1,zypper ve -D -y 显示 Dependencies of all installed packages are satisfied.。

💡 说明: 该场景的通用价值在于方法论:动态库报错先反查提供者(se --provides),再校验依赖图(ve),最后最小化修复(ve -y 只补缺口,不像重装 jq 那样大动干戈)。同类事故还有一个常见来源——用 rpm -e --nodeps 强拆包,巡检时 zypper ve 一次就能把历史欠账全部揪出来。

4.4 场景四:本地软件源搭建与内网分发

内网环境无法直连公网源时的最小可用方案(0 到 1 全流程,实测见 3.16):

zypper in -y createrepo_c                          # 元数据构建工具
zypper download tree bc htop                       # 把需要的 rpm 下进包缓存
mkdir -p /srv/repo-local
cp /var/cache/zypp/packages/openSUSE:repo-oss/%2E%2E/x86_64/*.rpm /srv/repo-local/
createrepo_c /srv/repo-local                       # 生成 repodata
zypper ar /srv/repo-local repo-local               # 添加为 dir: 源
zypper --no-gpg-checks ref repo-local              # 未签名,需放行 GPG 检查
zypper --no-gpg-checks in -y -r repo-local tree    # 只从这个源安装

正式一点的做法:给源签名后用 mr --gpgcheck-allow-unsigned-repo 的替代——把导出的 GPG 公钥放进 gpgkey 配置,免去 --no-gpg-checks。源定义直接落盘 /etc/zypp/repos.d/repo-local.repo(baseurl=dir:/srv/repo-local),分发到内网机器时改 baseurl 为 http://内网地址/repo-local/ 即可复用同一份 repodata。

💡 说明: zypper download 与 in -d 的区别:前者永远只下载(已装也下),后者是安装事务的「仅下载」模式;两者产物都在 /var/cache/zypp/packages/<源别名>/ 下。内网分发时记得元数据里有哈希与文件清单(filelists/primary/other 三类 xml.zst),整目录 rsync 即可,不要只拷 rpm。

4.5 场景五:rpm 离线留存(keep-packages)

让某源下载过的 rpm 常驻缓存,做内网安装备份(实测 3.18 的延续):

zypper mr -k openSUSE:repo-oss    # 开启该源的 rpm 留存(会带 volatile 警告)
zypper in -y sl                   # 安装演示包
ls -R /var/cache/zypp/packages    # sl 的 rpm 已留存
zypper mr -K openSUSE:repo-oss    # 还原默认不留存
zypper rm -y sl                   # 清理演示包

实测缓存内容:

/var/cache/zypp/packages/openSUSE:repo-oss/%2E%2E/x86_64:
sl-5.05-bp160.1.3.x86_64.rpm
tree-2.2.1-160000.2.2.x86_64.rpm
zip-3.0-160000.2.2.x86_64.rpm

💡 说明: 在 Leap 16 上对服务托管源开 -k 会得到 [volatile] 与 reset 警告(见 3.2)——真正持久的做法是给自建源(非服务托管)开 -k,或在 /etc/zypp/zypp.conf 全局配置。留存目录里的 %2E%2E(URL 转义的 ..)属于 libzypp 的介质路径布局,不影响使用;做离线备份时直接以整目录为单位拷贝。

五、注意事项与常见问题

Q1:为什么 zypper ref repo-oss 报 not found,老教程都这么写? Leap 16.0 的默认源由 openSUSE 服务托管,完整别名带 openSUSE: 前缀。实测三种正确写法:zypper ref openSUSE:repo-oss、zypper ref 4(编号见 lr 首列)、zypper ref(全刷)。短别名报错退出码 3。同理,mr/lr/rr 操作这些源时也要用完整别名,且修改属性会收到 [volatile] 警告(服务刷新后重置)。

Q2:脚本里跑 zypper 报 Cannot read input: bad stream or EOF 怎么办? 这是 zypper 在无终端环境下遇到提问(如未签名源确认)且读不到输入时的标准报错(3.16 实测原文)。解法按场景选:事务确认用 -y 或全局 -n;GPG 提示用 --no-gpg-checks(内网自建源)或 --gpg-auto-import-keys(有新密钥要信任)。注意 -n 的默认答案对未签名源是 no,会直接中止刷新。

Q3:退出码 100 是出错了吗? 不是。pchk 用退出码表意:0=无待打补丁,100=有补丁待处理(实测)。这来自「检查类命令」的设计,类似 grep 的 0/1/2。巡检脚本里 zypper pchk; [ $? -eq 100 ] && 需要打补丁 是标准写法。其余常用码见 3.19 实测表(3=源没找到、4=执行出错、104=对象不存在)。

Q4:up、patch、dup 到底怎么选? 日常维护 zypper up(保守,不降级不换 vendor);安全基线 zypper patch --category security(只动补丁语义内的包);版本迁移或大幅换源后 zypper dup 收口(允许降级/换 vendor/清孤儿)。Leap 16 无独立 update 源,补丁元数据随 repo-oss 分发,三者数据同源,语义差别在动作范围。dup 前必须 -D 干跑审阅 REMOVED 清单。

Q5:为什么本机找不到独立的 update 软件源?Leap 15 的教程说要加一个? Leap 16.0 的更新直接发布在主源 repo-oss 中(lp/pchk 直接从 repo-oss 的元数据读取补丁),官方不再提供旧式的 /update/leap/16.0/ 独立更新源目录(实测该路径已返回 404)。Leap 15.x 老教程里「先加 update 源再 patch」的步骤在 16.0 上不需要也不可用。

Q6:装完补丁/升级后怎么判断要不要重启? 两步:zypper needs-rebooting(内核/核心库被更新时置位,输出 Reboot is probably necessary.);zypper ps(列出仍在使用已删除文件/库的进程,需 lsof 包)。实测健康状态两者都给出 Reboot is probably not necessary. / No processes using deleted files found.。lp 输出里 Interactive 列为 reboot 的补丁,装完必查这两条。

Q7:缓存目录里的 %2E%2E 是乱码吗?要不要清掉? 不是乱码,是 URL 转义后的「..」,libzypp 按源的介质路径组织包缓存目录的正常产物(3.8/4.5 实测路径原样照抄)。清理用 zypper clean(包缓存)/clean -a(连元数据,实测回收约 78 MiB),不要手工 rm——手工删掉元数据缓存虽然下次会重建,但不如 clean -a 干净。

Q8:zypper ps 报 Please install package 'lsof' first.?还有哪些包在最小化环境里会「意外缺失」? ps 依赖 lsof(3.18 实测)。实测同批缺失的还有 which(改用 command -v)、find(findutils 包)。最小化 Leap 16 一共 121 个包,运维常用的不少工具都要现装:zypper in -y lsof findutils which 一次补齐,另建议把 zypper in -y lsof 写进升级后检查的前置步骤。

Q9:为什么 zypper lr 会输出 Repository priorities are without effect? 这是提示而非错误:所有已启用源优先级相同(默认 99)时优先级机制不参与选包决策。设置任一源为非 99(如 3.5 的 mr -p 50)后,输出会变为 Repository priorities in effect 并列出分布。选包优先级与源可靠性无关——别用优先级去「压制」一个不安全的源,直接 mr -d 禁用它。

Q10:zypper wp tree 提示被 replaced 了,还能用吗? 实测输出明确提示 Command 'what-provides' is replaced by 'search --provides --match-exact'.,旧命令目前仍会执行等价查询,但已列入弃用路径,新脚本一律写 zypper se --provides <能力> --match-exact(3.18 实测形式)。

六、参考链接