emerge 命令详解与参数实测(Gentoo Linux)
在 Gentoo Linux 实测 emerge 包管理器:--sync/--ask/--pretend/--autounmask/--depclean 等参数逐项回显与内网代理环境同步排障实录
emerge 命令详解与参数实测(Gentoo Linux)
目标:全面掌握 Gentoo Linux 包管理器 emerge 的每一个常用操作——
--sync同步软件树、--ask交互确认、--pretend/-pv依赖预演、--search搜索、--info环境信息、--depclean孤儿清理、--unmerge卸载、--resume中断恢复、--onlydeps/--oneshot/--noreplace/--deselect安装面控制、--update/--newuse全量维护、--autounmask关键字与 USE 标志协商、--config/--quiet辅助操作,以及内网代理环境下的 webrsync 引导 + git 同步标准方案,全部命令与回显已在 Gentoo Linux(Portage 3.0.82.2)实测通过。
一、环境信息
本文所有命令均在以下环境实测,回显逐字照抄(版本号均来自实测输出,未做任何推算):
- 操作系统:Gentoo Linux(
cat /etc/gentoo-release实测Gentoo Base System release 2.18;/etc/os-release实测PRETTY_NAME='Gentoo Linux'、VERSION_ID='2.18') - 内核架构:x86_64(
uname -m实测),宿主内核 6.8.0-138-generic(emerge --info实测显示) - 包管理器:Portage 3.0.82.2(
emerge --version实测,Python 3.14.7-final-0),仓库中 sys-apps/portage 最新为 3.0.82.2-r1 - 构建工具链:gcc 16.2.1_p20260926、glibc 2.43-r4、binutils 2.47、bash 5.3_p15(
emerge --info实测) - Profile:default/linux/amd64/23.0
- CPU/内存:12 核(
nproc实测),内存 32 GiB(emerge --info实测KiB Mem: 32819636 total) - 初始状态:最小化基础系统(stage3 模式安装),
/var/lib/portage/world为空文件;portage 软件树目录/var/db/repos/gentoo存在但为空(首次使用需同步) - 网络环境:内网服务器,出网经 HTTP 代理
http://192.168.1.62:7897(export http_proxy=http://192.168.1.62:7897 https_proxy=http://192.168.1.62:7897) - 演示包(体积小、便于反复装卸):sys-apps/pv 1.10.4(后经 keyword 放行升级 1.12.0)、app-misc/tmux 3.6a(连带依赖 dev-libs/libevent 2.1.13)、sys-process/time 1.10、app-portage/portage-utils 0.97.1(基础系统自带)
- 辅助工具:dev-vcs/git 2.55.0(为 git 方案同步软件树而编译安装)
💡 说明:emerge 是 Portage 的命令行前端,没有独立的"emerge 版本号",
emerge --version报的是 Portage 版本;查询本文结论对应的环境用emerge --version,查 Portage 包自身版本用emerge -s '^portage$'(2.2 节实测)。
二、命令概览
2.1 操作模型与 --help 全量回显
emerge 的操作模型与二进制发行版的包管理器不同:它没有"安装命令 + 查询命令"的字母分区(如 pacman 的 -S/-Q/-R、apt 的 install/search),而是统一 emerge [options] [action] [atom|@set] 一个入口,靠 action 参数区分动作。先看 emerge --help 的完整实测输出(Portage 3.0.82.2,逐字照抄):
emerge: command-line interface to the Portage system
Usage:
emerge [ options ] [ action ] [ ebuild | tbz2 | file | @set | atom ] [ ... ]
emerge [ options ] [ action ] < @system | @world >
emerge < --sync | --metadata | --info >
emerge --resume [ --pretend | --ask | --skipfirst ]
emerge --help
Options: -[abBcCdDefgGhjkKlnNoOpPqrsStuUvVwW]
[ --color < y | n > ] [ --columns ]
[ --complete-graph ] [ --deep ]
[ --jobs JOBS ] [ --keep-going ] [ --load-average LOAD ]
[ --newrepo ] [ --newuse ] [ --noconfmem ] [ --nospinner ]
[ --oneshot ] [ --onlydeps ] [ --quiet-build [ y | n ] ]
[ --reinstall changed-use ] [ --with-bdeps < y | n > ]
Actions: [ --depclean | --list-sets | --search | --sync | --version ]
For more help consult the man page.
逐项解读这份实测输出,有几个要点:
atom指依赖原子,如sys-apps/pv、=sys-apps/pv-1.12.0、sys-apps/pv[-nls](带 USE 约束);@set指软件集合,最常用@world(world 集合 + system 集合的全部包)。ebuild | tbz2 | file:emerge 还可以直接安装 ebuild 文件与本地质检包(.tbz2),不依赖软件树,本文以树内 atom 为主线。- 与 pacman 不同,这份
--help是精简速查:--pretend、--ask、--unmerge、--sync、--search等常用长参数与单字母缩写(-pv、-C、-1等)并未全部列出,完整参数清单要看man emerge。这是实测确认的第一处"与直觉不符"——不少教程照搬 pacman 的经验以为--help是全集,实际不是。 Options: -[abBcCdDefgGhjkKlnNoOpPqrsStuUvVwW]里的单字母与长参数的对应关系(如-p/--pretend、-a/--ask、-C/--unmerge、-u/--update、-1/--oneshot、-N/--newuse、-s/--search、-v/--verbose、-q/--quiet、-n/--noreplace),下文 3.x 节逐个实测。
💡 技术拓展:按分发形态,主流 Linux 包管理体系分源码编译型与二进制型两类,emerge 是源码编译型的代表——
体系 代表发行版 分发形态 特点与取舍 Portage + emerge Gentoo 源码为主(可配 binhost) USE 标志裁剪功能、编译耗时长、依赖解析强 pacman Arch 二进制滚动 装得快、滚得快,无编译期定制 apt/dpkg Debian/Ubuntu 二进制固定版 仓库分 stable 版本线,稳定但版本旧 dnf/rpm Fedora/RHEL 二进制(模块流) 版本生命周期明确,企业支持好 apk Alpine 二进制轻量 面向轻量环境/小体积,功能精简 zypper/rpm openSUSE 二进制 快照回滚(btrfs)集成 Gentoo 也支持二进制分发:
emerge优先走源码编译,配置 binhost(PORTAGE_BINHOST或默认 binhost 仓库)后可下载预编译包直接安装,本文实测环境未启用 binhost,全部为源码编译路径。
2.2 版本信息
确认环境的 Portage 版本,三条实测路径。第一,emerge --version(软件树同步完成后的正常输出,实测):
Portage 3.0.82.2 (python 3.14.7-final-0, default/linux/amd64/23.0, gcc-16, glibc-2.43-r4, 6.8.0-138-generic x86_64)
第二,在软件树缺失的初始状态执行 emerge --version(实测,用于认识其容错输出):
!!! Section 'gentoo' in repos.conf has location attribute set to nonexistent directory: '/var/db/repos/gentoo'
!!! Invalid Repository Location (not a dir): '/var/db/repos/gentoo'
Portage 3.0.82.2 (python 3.14.7-final-0, unavailable, gcc-16, glibc-2.43-r4, 6.8.0-138-generic x86_64)
树缺失时照样能打印版本,但 profile 段显示 unavailable,且 !!! 警告指出 repos.conf 里配置的树目录不存在。第三,查 Portage 包自身的最新版本,用 emerge -s '^portage$' 搜索结果(实测节选):
* sys-apps/portage
Latest version available: 3.0.82.2-r1
Latest version installed: 3.0.82.2-r1
Size of files: 1279 KiB
Homepage: https://wiki.gentoo.org/wiki/Project:Portage
Description: The package management and distribution system for Gentoo
License: GPL-2
💡 说明:
emerge --version输出括号里依次是 Python 版本、当前 profile、gcc 大版本、glibc 版本、宿主内核——一行输出同时可当作"环境体检卡"用。若括号里 profile 段是unavailable或 profile 路径,说明软件树/profile 未就绪,先做 3.5 节的--sync。
2.3 测试数据准备
本文实测按"全新最小系统"推进,共动了三处系统配置、三类演示包,先交代清楚,便于复现。
其一,构建参数。/etc/portage/make.conf 为 stage3 自带(CFLAGS="-O2 -pipe"、GENTOO_MIRRORS="http://distfiles.gentoo.org"),实测追加了两个变量:
# 追加到 /etc/portage/make.conf(实测)
MAKEOPTS="-j12" # 并行编译线程数,与 nproc 一致
FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox" # 关闭三个依赖 unshare 的沙箱特性(见 FAQ Q4)
其二,软件树。初始状态 /var/db/repos/gentoo 为空目录,按 3.5 节实测流程先 emerge-webrsync 引导、后切换 git 同步;树就位后 git log -1 实测 HEAD 为 edf4cb09937ae6320d49052d1a8596e06255c684(2026-10-16 提交),即树的内容新鲜度到实测前一天。
其三,演示包与 world 文件。/var/lib/portage/world 是"显式安装集合"的登记文件,初始为空。全部实测完成后的终态(实测 cat /var/lib/portage/world):
app-portage/portage-utils
dev-vcs/git
sys-apps/pv
三个包全部来自实测安装:portage-utils(基础系统自带,--noreplace/-N/USE 标志演示的载体)、git(webrsync→git 同步方案中编译安装)、pv(--ask 真实 0→1 安装 + keyword 放行升级的载体)。portage-utils 自带的 q 系查询工具是 Gentoo 服务器日常巡检主力,实测工具清单(ls /usr/bin/q*):
/usr/bin/q
/usr/bin/qatom
/usr/bin/qcheck
/usr/bin/qdepends
/usr/bin/qfile
/usr/bin/qgrep
/usr/bin/qkeyword
/usr/bin/qlist
/usr/bin/qlop
/usr/bin/qmanifest
/usr/bin/qmerge
/usr/bin/qpkg
/usr/bin/qsearch
/usr/bin/qsize
/usr/bin/qtbz2
/usr/bin/qtegrity
/usr/bin/quickpkg
/usr/bin/quse
/usr/bin/qwhich
/usr/bin/qxpak
工具集版本验证(实测 q --version):
portage-utils-0.97.1
written for Gentoo by solar, vapier and grobian
⚠️ 注意:老教程里常见
qu命令(query user?)在 portage-utils 0.97.1 中已不存在(实测qu报command not found),代之以q系列与quse;写脚本时不要照抄十年前文档的qu。
三、参数逐项实测
3.1 --ask / -a:安装前确认
--ask(缩写 -a)在执行前把"将合并哪些包"列出来并等待 Yes/No 确认,是 emerge 交互安装的标准姿势。先实测一个非终端环境的行为(直接在脚本里跑,stdin 不是 tty),回显逐字照抄:
!!! "--ask" should only be used in a terminal. Exiting.
实测退出码为 1,且拒绝发生在依赖解析之前——这与 pacman 非 tty 时"读 stdin 到 EOF 直接选默认值"完全不同,emerge 是硬拒绝。交互确认必须用伪终端。实测用 script -qec 包一层分配 pty,先看应答 No(实测 printf 'No\n' | script -qec "emerge --color n --nospinner -a app-misc/tmux" /dev/null):
No
* IMPORTANT: 19 news items need reading for repository 'gentoo'.
* Use eselect news read to view new items.
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.59 s (backtrack: 0/20).
[ebuild N ] dev-libs/libevent-2.1.13 USE="clock-gettime ssl -debug -malloc-replacement -static-libs -test -verbose-debug -verify-sig" ABI_X86="(64) -32 (-x32)"
[ebuild N ] app-misc/tmux-3.6a USE="-debug -jemalloc (-selinux) -sixel -systemd -utempter -vim-syntax"
Would you like to merge these packages? [Yes/No]
Quitting.
应答 No 后实测退出码 130,which tmux 确认未安装。再看应答 Yes 的完整 0→1 安装(sys-apps/pv,实测 printf 'Yes\n' | script -qec "emerge --color n --nospinner -a sys-apps/pv" /dev/null,输出为节选,省略段均已标注):
Yes
* IMPORTANT: config file '/etc/portage/package.accept_keywords/zz-autounmask' needs updating.
* See the CONFIGURATION FILES and CONFIGURATION FILES UPDATE TOOLS
* sections of the emerge man page to learn more.
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.25 s (backtrack: 0/20).
[ebuild N ~] sys-apps/pv-1.12.0 USE="ncurses nls -debug -verify-sig"
Would you like to merge these packages? [Yes/No]
>>> Verifying ebuild manifests
>>> Emerging (1 of 1) sys-apps/pv-1.12.0::gentoo
>>> Downloading 'http://distfiles.gentoo.org/distfiles/4a/pv-1.12.0.tar.gz'
--2026-10-17 00:41:40-- http://distfiles.gentoo.org/distfiles/4a/pv-1.12.0.tar.gz
Connecting to 192.168.1.62:7897... connected.
Proxy request sent, awaiting response... 200 OK
Length: 489837 (478K) [application/gzip]
Saving to: '/var/cache/distfiles/pv-1.12.0.tar.gz.__download__'
(……中间输出节选:下载进度条与校验行……)
* pv-1.12.0.tar.gz BLAKE2B SHA512 size ;-) ... [ ok ]
* Determining the location of the kernel source code
* Unable to find kernel sources at /usr/src/linux
(……中间输出节选:内核源码缺失警告四行,详见 FAQ Q8……)
>>> Unpacking source...
>>> Unpacking 'pv-1.12.0.tar.gz' to /var/tmp/portage/sys-apps/pv-1.12.0/work
>>> Source unpacked in /var/tmp/portage/sys-apps/pv-1.12.0/work
>>> Preparing source in /var/tmp/portage/sys-apps/pv-1.12.0/work/pv-1.12.0 ...
>>> Source prepared.
>>> Configuring source in /var/tmp/portage/sys-apps/pv-1.12.0/work/pv-1.12.0 ...
./configure --prefix=/usr --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --datarootdir=/usr/share --disable-dependency-tracking --disable-silent-rules --docdir=/usr/share/doc/pv-1.12.0 --htmldir=/usr/share/doc/pv-1.12.0/html --libdir=/usr/lib64 --disable-debugging --with-ncurses --enable-nls
(……中间输出节选:configure 逐项检测约 130 行 checking……)
>>> Source configured.
>>> Compiling source in /var/tmp/portage/sys-apps/pv-1.12.0/work/pv-1.12.0 ...
make -j12
(……中间输出节选:约 35 个 .c 文件逐个 gcc -c 编译……)
>>> Source compiled.
>>> Test phase [not enabled]: sys-apps/pv-1.12.0
>>> Install sys-apps/pv-1.12.0 into /var/tmp/portage/sys-apps/pv-1.12.0/image
make -j12 DESTDIR=/var/tmp/portage/sys-apps/pv-1.12.0/image install
(……中间输出节选:多语言 .mo 与文档逐个 install……)
>>> Completed installing sys-apps/pv-1.12.0 into /var/tmp/portage/sys-apps/pv-1.12.0/image
* Final size of build directory: 3080 KiB (3.0 MiB)
* Final size of installed tree: 580 KiB
strip: x86_64-pc-linux-gnu-strip --strip-unneeded -N __gentoo_check_ldflags__ -R .comment -R .GCC.command.line -R .note.gnu.gold-version
/usr/bin/pv
>>> Installing (1 of 1) sys-apps/pv-1.12.0::gentoo
>>> Recording sys-apps/pv in "world" favorites file...
>>> Completed (1 of 1) sys-apps/pv-1.12.0::gentoo
* Messages for package sys-apps/pv-1.12.0:
* Unable to find kernel sources at /usr/src/linux
* Unable to calculate Linux Kernel version for build, attempting to use running version
* Unable to check for the following kernel config options due
* to absence of any configured kernel sources or compiled
* config:
* - SYSVIPC - You will need to enable CONFIG_SYSVIPC in your kernel to use the --remote option.
* You're on your own to make sure they are set if needed.
这就是 Gentoo 安装一个包的完整生命周期:确认 → manifest 校验 → 下载 → 解包 → 准备 → 配置 → 编译 → 安装镜像 → strip → 落盘 → 记入 world。验证安装生效(实测):
$ pv --version
pv 1.12.0
Copyright 2026 Andrew Wood
License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Project web site: <https://ivarch.com/p/pv>
功能验证(实测 echo 'hello emerge' | pv -qL 20,输出为限速回放本身,无报错即正常)。同时确认 world 登记生效(实测 cat /var/lib/portage/world,此时内容含 sys-apps/pv)。
💡 说明:
[ebuild N ~]中的N= new(新装)、~= 该版本需要~amd64keyword(测试关键字,见 3.18 节);本次应答 Yes 后装的是 1.12.0 而非稳定版 1.10.4,因为 3.18 节的 keyword 放行已生效。纯新装不带 keyword 议题时,-a显示N且无~(对比 3.1 第一段 tmux 的回显)。
3.2 --pretend / -p:只解析依赖不执行
--pretend(缩写 -p)把"将要做什么"完整算出来打印,不下载、不编译、不改系统,是生产环境变更前的标准动作。实测 emerge -p app-portage/portage-utils:
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.53 s (backtrack: 0/20).
[ebuild R ] app-portage/portage-utils-0.97.1 USE="openmp*"
* IMPORTANT: 19 news items need reading for repository 'gentoo'.
* Use eselect news read to view new items.
[ebuild R ] 的 R = reinstall(同版本将重装,因为该包已在系统里且 USE 与当前配置有差异)。-p 配合带依赖的包看得更清楚——先卸掉依赖再预演(呼应 3.15 节),实测 emerge -pv app-misc/tmux(libevent 未装时):
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.29 s (backtrack: 0/20).
[ebuild N ] dev-libs/libevent-2.1.13:0/2.1-7::gentoo USE="clock-gettime ssl -debug -malloc-replacement -static-libs -test -verbose-debug -verify-sig" ABI_X86="(64) -32 (-x32)" 1101 KiB
[ebuild N ] app-misc/tmux-3.6a::gentoo USE="-debug -jemalloc (-selinux) -sixel -systemd -utempter -vim-syntax" 734 KiB
Total: 2 packages (2 new), Size of downloads: 1834 KiB
Total 行给出包数与总下载量,容量规划一目了然。-p 对被掩码的包也有价值——掩码错误是预演阶段(而非安装中途)暴露的,实测 emerge -pv '=sys-apps/pv-1.12.0'(keyword 未放行时):
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.25 s (backtrack: 0/20).
!!! All ebuilds that could satisfy "=sys-apps/pv-1.12.0" have been masked.
!!! One of the following masked packages is required to complete your request:
- sys-apps/pv-1.12.0::gentoo (masked by: ~amd64 keyword)
For more information, see the MASKED PACKAGES section in the emerge
man page or refer to the Gentoo Handbook.
⚠️ 注意:
-p只是"不执行",但依赖解析本身会消耗真实时间(大 world 集合可达数分钟),脚本里频繁-p也算负载;且-p不刷新软件树,树过期时预演结果可能与实际安装时不同(搭配 3.5 节先--sync)。
3.3 -pv:--verbose + --tree 依赖树与 USE 明细
-pv 是 Gentoo 运维最常用的组合:--verbose 在每行包后面追加 USE 标志明细、下载体积、slot 版本,--tree 控制按依赖顺序展示。3.2 节的 -pv 输出已经展示了大部分信息,这里重点解读 USE 字段(以 libevent 一行为例,实测原文):
[ebuild N ] dev-libs/libevent-2.1.13:0/2.1-7::gentoo USE="clock-gettime ssl -debug -malloc-replacement -static-libs -test -verbose-debug -verify-sig" ABI_X86="(64) -32 (-x32)" 1101 KiB
字段逐项说明:2.1.13:0/2.1-7 为 版本:slot/子slot;::gentoo 为来源仓库;USE="..." 里无前缀 = 启用、- 前缀 = 关闭、() 包裹 = 被当前 profile 强制/锁定不可改、带 * = 与该包上次构建相比发生了变化;ABI_X86="(64) -32 (-x32)" 为多ABI子槽选择,同样 () 表示被锁定;末尾数字为下载体积 KiB。
💡 技术拓展:USE 标志是 Gentoo 区别于所有二进制发行版的编译期功能开关——同一个包按标志组合裁出不同二进制。管理入口从粗到细三层——
层级 位置 作用域 本文用法 全局 USE make.conf USE="..."/ profile 默认全系统 基础系统自带,未改动 包级 USE /etc/portage/package.use/ 单包 3.17 节 -N演示翻转 portage-utils 的 openmp原子内联 USE 命令行 pkg[+use,-use]单次请求 3.18 节实测其与配置文件的协商行为 本文实测采用包级 package.use 文件做持久变更(K 段实测 openmp 关闭/恢复两轮重编译),命令行内联只做临时预演;
emerge --info <pkg>的 "Package Settings" 段可查"该包当前实际构建时的 USE"(3.6 节)。
3.4 --search / -s:搜索软件树
--search(缩写 -s)按正则搜软件树。精确搜索包名(实测 emerge -s '^pv$'):
[ Results for search key : ^pv$ ]
Searching...
* sys-apps/pv
Latest version available: 1.10.4
Latest version installed: [ Not Installed ]
Size of files: 430 KiB
Homepage: https://ivarch.com/p/pv https://codeberg.org/ivarch/pv
Description: Pipe Viewer: a tool for monitoring the progress of data through a pipe
License: GPL-3+
[ Applications found : 1 ]
Latest version available 是树里的最新版(受 keyword 掩码影响的稳定视角),Latest version installed 是本机安装状态,[ Not Installed ] 未装。范围搜索时一个 key 命中多个包(实测 emerge -s '^portage' 节选):
[ Results for search key : ^portage ]
Searching...
* acct-group/portage
Latest version available: 0-r2
Latest version installed: 0-r2
Size of files: 0 KiB
Homepage:
Description: System group: portage
License:
* app-metrics/portage-exporter [ Masked ]
Latest version available: 0.1.0
Latest version installed: [ Not Installed ]
Size of files: 15 KiB
Homepage: https://github.com/projg2/portage-exporter
Description: Prometheus exporter for Gentoo Portage
License: GPL-3
* app-portage/portage-utils
Latest version available: 0.97.1
Latest version installed: 0.97.1
Size of files: 1927 KiB
Homepage: https://wiki.gentoo.org/wiki/Portage-utils
Description: Small and fast Portage helper tools written in C
License: GPL-2
* sys-apps/portage
Latest version available: 3.0.82.2-r1
Latest version installed: 3.0.82.2-r1
Size of files: 1279 KiB
Homepage: https://wiki.gentoo.org/wiki/Project:Portage
Description: The package management and distribution system for Gentoo
License: GPL-2
[ Applications found : 5 ]
注意 app-metrics/portage-exporter [ Masked ]:被掩码的包在搜索结果里带 [ Masked ] 标记但不给原因,原因要看 emerge -pv <atom>(3.2 节的 masked by: ~amd64 keyword)。搜索只查树内包名与描述;要搜文件属于哪个包用 q 系工具(qfile)。
3.5 --sync:同步软件树(内网代理环境:webrsync 引导 + git 同步标准方案)
--sync 把 portage 软件树(ebuild 全集 + profile + metadata)更新到最新。它是本文所有实测的前置,也是 Gentoo 与内网代理环境交集最大、最容易踩坑的操作,这里给完整实测链路。
先看出厂配置。树同步方式由 /usr/share/portage/config/repos.conf(默认值,实测摘录)定义:
[DEFAULT]
main-repo = gentoo
[gentoo]
location = /var/db/repos/gentoo
sync-type = rsync
sync-uri = rsync://rsync.gentoo.org/gentoo-portage
auto-sync = yes
sync-rsync-verify-jobs = 1
sync-rsync-verify-metamanifest = yes
sync-rsync-verify-max-age = 3
sync-openpgp-key-package = sec-keys/openpgp-keys-gentoo-release
sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc
sync-openpgp-keyserver = hkps://keys.gentoo.org
sync-webrsync-verify-signature = yes
sync-git-verify-commit-signature = true
默认 sync-type = rsync。坑在这里:rsync 协议(873 端口)不走 http_proxy/https_proxy,http_proxy 只对 HTTP(S) 生效。实测本网络 873 端口可达、能列出模块(rsync rsync.gentoo.org::gentoo-portage 返回模块列表),但生产 rsync 拉全树仍然受网络策略波动影响,且 rsync 大树传输在内网出口也不稳定。内网代理环境的标准做法是改用 git 同步(HTTPS 443,天然走代理),而切 git 又遇到一个鸡生蛋问题:本环境的基础系统没有预装 git(实测 git --version 报 command not found),装 git 又需要先有软件树。
分三步走,全程实测。
第一步:emerge-webrsync 引导出树。 webrsync 通过 HTTP(S) 下载每日树快照(走代理),不依赖 rsync/git。实测 emerge-webrsync(输出节选):
* Getting snapshot timestamp ...
* Extracting 'gentoo-20261015.tar.xz' ...
* Using rsync to refresh '/var/db/repos/gentoo' ...
Number of files: 161,508 (reg: 133,610, dir: 27,898)
Number of created files: 161,507 (reg: 133,610, dir: 27,897)
Number of deleted files: 0
Number of regular files transferred: 133,610
Total file size: 250.08M bytes
Total transferred file size: 250.08M bytes
Literal data: 250.08M bytes
File list size: 4.06M
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 127.37M
Total bytes received: 2.66M
树就位验证(实测):
$ cat /var/db/repos/gentoo/profiles/repo_name
gentoo
$ emerge --version
Portage 3.0.82.2 (python 3.14.7-final-0, default/linux/amd64/23.0, gcc-16, glibc-2.43-r4, 6.8.0-138-generic x86_64)
profile 段从 2.2 节的 unavailable 变成了 default/linux/amd64/23.0,依赖解析恢复可用。
⚠️ 注意:实测发现若先把
/etc/portage/repos.conf/gentoo.conf写成sync-type = git,emerge-webrsync会拒绝执行(webrsync 只认 rsync/webrsync 类型的同步配置)。正确顺序是"webrsync 引导 → 装 git → 再切 git 配置",顺序颠倒会卡死在新机器上。
第二步:编译安装 git。 git 的默认 USE 会拖入 rust 等重型依赖(emerge -pv dev-vcs/git 实测确认),用包级 USE 裁剪后安装(实测命令与安装尾部回显):
mkdir -p /etc/portage/package.use
cat > /etc/portage/package.use/git <<'EOF'
dev-vcs/git -rust -perl -gpg -webdav -pcre -subversion -tk -highlight -keyring
EOF
emerge -v dev-vcs/git
* Note that the prompt bash code is now in that separate script
* Some scripts require additional dependencies:
* dev-util/quilt for git-quiltimport
* www-servers/lighttpd for git-instaweb
* www-servers/apache for git-instaweb
* www-servers/nginx for git-instaweb
* GNU info directory index is up-to-date.
* IMPORTANT: 19 news items need reading for repository 'gentoo'.
* Use eselect news read to view new items.
验证(实测 git --version):git version 2.55.0。
第三步:git clone 换树 + 常驻 git 同步配置。 实测把 webrsync 树让位给 git 树并计时:
mv /var/db/repos/gentoo /var/db/repos/gentoo.webrsync-bak
time git clone --depth 1 https://github.com/gentoo/gentoo.git /var/db/repos/gentoo
Cloning into '/var/db/repos/gentoo'...
Updating files: 100% (94197/94197), done.
real 0m9.397s
user 0m2.309s
sys 0m2.638s
94197 个文件、实测 du -sh 601 MiB、耗时 9.4 秒(代理链路良好时)。树身份验证(实测):
$ cat /var/db/repos/gentoo/profiles/repo_name
gentoo
$ git -C /var/db/repos/gentoo log --oneline -1
edf4cb099 dev-php/pecl-memcached: drop 3.3.0
$ git -C /var/db/repos/gentoo log -1 --format='%H %ci'
edf4cb09937ae6320d49052d1a8596e06255c684 2026-10-16 18:24:56 -0400
清理备份后写入常驻配置(实测 /etc/portage/repos.conf/gentoo.conf 全文):
[gentoo]
location = /var/db/repos/gentoo
sync-type = git
sync-uri = https://github.com/gentoo/gentoo.git
sync-git-clone-extra-opts = --depth 1
sync-git-fetch-extra-opts = --depth 1
sync-git-verify-commit-signature = false
auto-sync = yes
之后日常同步就是 emerge --sync,实测完整回显(git 增量已是最新时的状态):
>>> Syncing repository 'gentoo' into '/var/db/repos/gentoo'...
/usr/sbin/git fetch origin --depth 1
/usr/sbin/git reset --merge refs/remotes/origin/master
=== Sync completed for gentoo
* IMPORTANT: 2 config files in '/etc' need updating.
* See the CONFIGURATION FILES and CONFIGURATION FILES UPDATE TOOLS
* sections of the emerge man page to learn how to update config files.
Action: sync for repo: gentoo, returned code = 0
从 webrsync 树切到 git 树后的首次 emerge --sync 会多一段 profile updates 处理(实测节选,逐个重放 profiles/updates/ 下的迁移指令):
/var/db/repos/gentoo/profiles/updates/4Q-2025...
/var/db/repos/gentoo/profiles/updates/2Q-2025......
/var/db/repos/gentoo/profiles/updates/2Q-2023..............................
(……中间输出节选:十余个季度更新文件……)
Action: sync for repo: gentoo, returned code = 0
⚠️ 注意两个实测差异:其一,git 树没有
/var/db/repos/gentoo/metadata/timestamp.chk(rsync/webrsync 树才有,实测cat报No such file or directory),判断树的新旧用git -C /var/db/repos/gentoo log -1或emerge --info的Head commit of repository gentoo行;其二,sync-git-verify-commit-signature = false是因为签名校验需要额外钥匙环,内网环境按需评估,默认配置文件里该值为true。
💡 技术拓展:Portage 树的同步方式不止一种,repos.conf 的
sync-type可选——
方式 协议/端口 代理友好度 特点 rsync rsync://(873/tcp) 差(不走 http 代理) 官方默认,增量快,带签名校验 webrsync HTTPS 快照 tar 好 每日快照整包,适合引导与受限网络 git HTTPS(443) 好 完整 git 历史、 --depth 1省空间,社区常用mercurial/svn 各自协议 视协议 少用 本文实测采用 webrsync 引导 + git 常驻(
sync-type = git)的组合,理由:rsync 无法复用 http_proxy,git 443 直接受代理保护且增量同步只拉取差异提交。
3.6 --info:环境与包构建信息
emerge --info 输出当前构建环境的完整变量表,报障时贴给搜索引擎/社区的第一手材料。实测头部节选(完整输出数百行):
Portage 3.0.82.2 (python 3.14.7-final-0, default/linux/amd64/23.0, gcc-16, glibc-2.43-r4, 6.8.0-138-generic x86_64)
=================================================================
System uname: Linux-6.8.0-138-generic-x86_64-Intel-R-_Core-TM-_i7-14700KF-with-glibc2.43
KiB Mem: 32819636 total, 801444 free
KiB Swap: 2097148 total, 2096624 free
Head commit of repository gentoo: edf4cb09937ae6320d49052d1a8596e06255c684
sh: bash 5.3_p15
coreutils: (GNU coreutils) 9.11
ld: GNU ld (Gentoo 2.47 p1) 2.47.0
app-misc/pax-utils: 1.3.11::gentoo
app-shells/bash: 5.3_p15::gentoo
dev-build/autoconf: 2.72-r7::gentoo
dev-build/automake: 1.18.1-r1::gentoo
dev-build/cmake: 4.3.4::gentoo
dev-build/libtool: 2.5.4::gentoo
dev-build/make: 4.4.1-r102::gentoo
dev-build/meson: 1.11.2::gentoo
dev-lang/perl: 5.44.0::gentoo
dev-lang/python: 3.14.7::gentoo
sys-apps/baselayout: 2.18-r1::gentoo
sys-apps/openrc: 0.63.3::gentoo
sys-apps/sandbox: 2.49::gentoo
sys-devel/binutils: 2.47::gentoo
sys-devel/binutils-config: 5.6::gentoo
sys-devel/gcc: 16.2.1_p20260926::gentoo
sys-devel/gcc-config: 2.12.2::gentoo
sys-kernel/linux-headers: 6.18::gentoo (virtual/os-headers)
sys-libs/glibc: 2.43-r4::gentoo
Repositories:
gentoo
location: /var/db/repos/gentoo
sync-type: git
sync-uri: https://github.com/gentoo/gentoo.git
priority: -1000
volatile: False
sync-git-clone-extra-opts: --depth 1
sync-git-verify-commit-signature: false
Head commit of repository gentoo 行即树的精确新鲜度(3.5 节 git 方案的收益)。--info 还能带 atom 参数,查指定包的构建现场,实测 emerge --info app-portage/portage-utils(尾部 Package Settings 段):
=================================================================
Package Settings
=================================================================
app-portage/portage-utils-0.97.1::gentoo was built with the following:
USE="qmanifest -openmp -static" ABI_X86="(64)"
FEATURES="assume-digests binpkg-docompress binpkg-dostrip binpkg-logs binpkg-multi-instance buildpkg buildpkg-live clean-logs compress-index config-protect-if-modified distlocks ebuild-locks fixlafiles ipc-sandbox merge-sync merge-wait multilib-strict network-sandbox parallel-fetch parallel-install pid-sandbox pkgdir-index-trusted preserve-libs protect-owned qa-unresolved-soname-deps sandbox strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync"
was built with the following: USE="..." 是该包落盘时的 USE 快照,与 3.3 节 -pv 预演里的"将要用的 USE"对照,差值就是 3.17 节 -N 要处理的内容。
3.7 --version:版本查询
emerge --version 的正常输出见 2.2 节。补充实测其异常场景下的行为差异:软件树缺失时(2.2 节第二段)照常打印版本但附 !!! 警告、profile 段为 unavailable;树正常时输出干净一行。该命令是只读操作,依赖解析都没有,任何状态都可直接跑,适合放进巡检脚本的开头。
3.8 --depclean:孤儿依赖清理
--depclean 移除"world 与 system 都不再需要"的包。它最典型的场景是配合卸载使用:-C 卸掉 tmux 后,它的依赖 libevent 就成了孤儿。实测 printf 'Yes\n' | script -qec "emerge --color n --nospinner -a --depclean" /dev/null(节选):
Yes
* Always study the list of packages to be cleaned for any obvious
* mistakes. Packages that are part of the world set will always
* be kept. They can be manually added to this set with
* `emerge --noreplace <atom>`. Packages that are listed in
* package.provided (see portage(5)) will be removed by
* depclean, even if they are part of the world set.
*
* As a safety measure, depclean will not remove any packages
* unless *all* required dependencies have been resolved. As a
* consequence of this, it often becomes necessary to run
* `emerge --update --newuse --deep @world` prior to depclean.
Calculating dependencies ... done!
>>> Calculating removal order...
>>> These are the packages that would be unmerged:
dev-libs/libevent
selected: 2.1.13
protected: none
omitted: none
All selected packages: =dev-libs/libevent-2.1.13
>>> 'Selected' packages are slated for removal.
>>> 'Protected' and 'omitted' packages will not be removed.
Would you like to unmerge these packages? [Yes/No] >>> Waiting 5 seconds before starting...
>>> (Control-C to abort)...
>>> Unmerging in: 5 4 3 2 1
>>> Unmerging (1 of 1) dev-libs/libevent-2.1.13...
Packages installed: 298
Packages in world: 2
Packages in system: 50
Required packages: 298
Number removed: 1
末尾统计块是 --depclean 的"体检报告":装机总量 298、world 集合 2、system 集合 50、本轮移除 1。幂等性实测(不带 -a 直接复跑 emerge --depclean):
>>> To see reverse dependencies, use --verbose
Packages installed: 298
Packages in world: 2
Packages in system: 50
Required packages: 298
Number removed: 0
Number removed: 0 确认收敛。指定包的反向依赖体检用 -pv --depclean <atom>,实测 emerge -pv --depclean app-portage/portage-utils:
Calculating dependencies ... done!
app-portage/portage-utils-0.97.1 pulled in by:
app-admin/perl-cleaner-2.31-r3 requires app-portage/portage-utils
>>> No packages selected for removal by depclean
Packages installed: 299
Packages in world: 2
Packages in system: 50
Required packages: 299
Number to remove: 0
pulled in by 列出反向依赖(perl-cleaner 需要它),结论 No packages selected for removal——这是卸载任何包前值得跑的"删了谁会哭"检查。
⚠️ 注意:官方提示写得很清楚,--depclean 前先跑
emerge --update --newuse --deep @world(3.16 节)把 world 内的依赖关系补齐,否则某些"看似孤儿"的包会被误删;本文实测顺序就是"更新 → 卸载 → depclean"。
3.9 --unmerge / -C:卸载包
--unmerge(缩写 -C,位置必须在最前,如 emerge -C <atom>)从系统移除包。先看非交互裸 -C 的实测行为(emerge -C sys-apps/pv):
* This action can remove important packages! In order to be safer, use
* `emerge -pv --depclean <atom>` to check for reverse dependencies before
* removing packages.
sys-apps/pv
selected: 1.10.4
protected: none
omitted: none
All selected packages: =sys-apps/pv-1.10.4
>>> 'Selected' packages are slated for removal.
>>> 'Protected' and 'omitted' packages will not be removed.
>>> Waiting 5 seconds before starting...
>>> (Control-C to abort)...
>>> Unmerging in: 5 4 3 2 1
>>> Unmerging (1 of 1) sys-apps/pv-1.10.4...
裸 -C 不问 Yes/No,但给 5 秒倒计时(Control-C 可中止)。交互式用 -aC,实测 printf 'Yes\n' | script -qec "emerge --color n --nospinner -aC app-misc/tmux" /dev/null(节选):
Yes
* This action can remove important packages! In order to be safer, use
* `emerge -pv --depclean <atom>` to check for reverse dependencies before
* removing packages.
>>> These are the packages that would be unmerged:
app-misc/tmux
selected: 3.6a
protected: none
omitted: none
All selected packages: =app-misc/tmux-3.6a
>>> 'Selected' packages are slated for removal.
>>> 'Protected' and 'omitted' packages will not be removed.
Would you like to unmerge these packages? [Yes/No] >>> Waiting 5 seconds before starting...
>>> (Control-C to abort)...
>>> Unmerging in: 5 4 3 2 1
>>> Unmerging (1 of 1) app-misc/tmux-3.6a...
卸载目标不存在时的实测行为(app-misc/most,emerge -aC app-misc/most 应答 Yes 后):
>>> These are the packages that would be unmerged:
--- Couldn't find 'app-misc/most' to unmerge.
>>> No packages selected for removal by unmerge
实测退出码 1。验证卸载生效(实测 which pv most):
which: no pv in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
which: no most in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
⚠️ 注意:
-C不清理孤儿依赖(tmux 走后 libevent 还在,需 3.8 节 --depclean 收尾),也不自动从 world 移除条目(world 里手动登记的 atom 会残留成"幽灵",配合 3.19 节 --deselect 或直接emerge --deselect)。删重要组件前先跑emerge -pv --depclean <atom>看反向依赖(3.8 节实测)。
3.10 --config:执行包的配置钩子
部分包(如 dev-db/mysql、sys-libs/glibc)在 ebuild 里定义了 pkg_config() 后处理函数(初始化数据库、生成配置等),emerge --config <atom> 触发它。没有定义 pkg_config 的包会报错,实测 emerge --config app-portage/portage-utils:
Configuring pkg...
* pkg_config() is not defined: 'portage-utils-0.97.1.ebuild'
* Messages for package app-portage/portage-utils-0.97.1:
* pkg_config() is not defined: 'portage-utils-0.97.1.ebuild'
哪些包有 config 钩子没有直接命令列出;常见的是数据库类(mysql/postgres 初始化)与目录服务类(openldap 等)。日常排查思路:报 pkg_config() is not defined 说明该包根本没有后处理需求,不用管。
3.11 --resume:恢复被中断的合并
编译型安装动辄数十分钟,--resume 专门救场:Portage 会记录上次合并队列,--resume 从未完成处继续。实测制造一次中断——后台启动 tmux 合并,3 秒后 kill 掉(实测,输出节选):
* Running eautoreconf in '/var/tmp/portage/app-misc/tmux-3.6a/work/tmux-3.6a' ...
* Running 'aclocal --system-acdir=/var/tmp/portage/app-misc/tmux-3.6a/temp/aclocal' ...
Exiting on signal 15
--- tmux 是否已装:
which: no tmux in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
Exiting on signal 15 即被 SIGTERM 打断,此时 tmux 未落盘。恢复(实测 emerge --resume,输出节选):
>>> /usr/share/man/man1/tmux.1.bz2
--- /usr/bin/
>>> /usr/bin/tmux
>>> app-misc/tmux-3.6a merged.
>>> Recording app-misc/tmux in "world" favorites file...
>>> Completed (1 of 1) app-misc/tmux-3.6a::gentoo
队列里只剩 tmux 一个包,直接续上直到完成。验证(实测 tmux -V):tmux 3.6a。恢复队列为空时的实测行为:
emerge: It seems we have nothing to resume...
💡 说明:
--resume可与--pretend/--ask/--skipfirst组合(--help的 Usage 行原文即emerge --resume [ --pretend | --ask | --skipfirst ]),--skipfirst用于跳过队列里反复失败的头一个包、从第二个继续。
3.12 --quiet / -q:精简输出
--quiet(缩写 -q)压缩输出量。对比实测:普通 -p 输出(3.2 节)每包一行带 USE 明细与统计;emerge -q --pretend sys-apps/pv 实测:
[ebuild N ] sys-apps/pv-1.10.4
USE 块、Calculating dependencies、Total 统计、news 提示全部消失,只剩 atom 行——脚本里抓包名列表(emerge -q --pretend <atom>)最干净。-q 用在真实安装上同样生效:合并过程只保留包级别的开始/完成行,编译细节全部静默,适合 cron 任务日志。
3.13 --noreplace / -n:已安装则跳过
默认行为:对已安装的包执行 emerge <pkg> 会重装(R)——实测 emerge -v app-portage/portage-utils 的合并尾部(重装落盘过程):
--- replaced sym /usr/bin/qdepends
--- replaced sym /usr/bin/qcheck
--- replaced sym /usr/bin/qatom
--- replaced obj /usr/bin/q
--- replaced dir /usr/bin
--- replaced dir /usr
>>> Original instance of package unmerged safely.
>>> app-portage/portage-utils-0.97.1 merged.
>>> Completed (1 of 1) app-portage/portage-utils-0.97.1::gentoo
--noreplace(缩写 -n)反转这个行为:已装包直接跳过。实测 emerge -v --noreplace app-portage/portage-utils:
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.24 s (backtrack: 0/20).
Total: 0 packages, Size of downloads: 0 KiB
Total: 0 packages,且该包仍会被记入 world(--noreplace 的语义是"确保它在"而非"重装一遍")。批量补登记 world 条目、脚本幂等化都靠它。与 3.14 节 --oneshot 正好是两个方向的配合:-n 管"装不装",-1 管"记不记 world"。
3.14 --oneshot / -1:安装但不记入 world
--oneshot(缩写 -1)照常安装,但不写入 world 文件——适合"临时装来用、以后让 depclean 收走"的场景。实测 emerge -1v sys-process/time(输出节选):
>>> Completed (1 of 1) sys-process/time-1.10::gentoo
* Regenerating GNU info directory index...
* Processed 105 info files.
工具可用(实测 /usr/bin/time --version):
time (GNU Time) 1.10
Copyright (C) 2026 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David Keppel, David MacKenzie, and Assaf Gordon.
world 对照(实测 cat /var/lib/portage/world):
app-portage/portage-utils
dev-vcs/git
sys-apps/pv
sys-process/time 不在 world 里——将来 --depclean 时若无其他包依赖它就会被收走。对照组:3.1 节不带 -1 安装的 pv 就在 world 里。
⚠️ 注意:老教程演示
--oneshot常用 app-misc/most,实测当前树里该包已被移除(emerge -1v app-misc/most报emerge: there are no ebuilds to satisfy "app-misc/most".且给出Maybe you meant any of these: app-misc/jot, app-misc/smtm, app-misc/note?)。树是活的,演示包先-s确认存在(详见 FAQ Q5)。
3.15 --onlydeps:只装依赖不装目标
--onlydeps 只安装指定 atom 的依赖,目标本身不装——典型用途:先备齐依赖再手工处理目标(如源码编译前备库)。实测 emerge -v --onlydeps app-misc/tmux(输出节选):
--- /usr/bin/
>>> /usr/bin/event_rpcgen.py
>>> /usr/lib64/libevent-2.1.so.7 -> libevent-2.1.so.7.0.2
>>> /usr/lib64/libevent.so -> libevent-2.1.so.7.0.2
>>> dev-libs/libevent-2.1.13 merged.
>>> Regenerating /etc/ld.so.cache...
>>> Completed (1 of 1) dev-libs/libevent-2.1.13::gentoo
只合并了 libevent。验证:依赖已装、目标未装(实测):
$ qlist -I dev-libs/libevent
dev-libs/libevent
$ emerge -pv app-misc/tmux
[ebuild N ] app-misc/tmux-3.6a::gentoo USE="-debug -jemalloc (-selinux) -sixel -systemd -utempter -vim-syntax" 734 KiB
Total: 1 package (1 new), Size of downloads: 734 KiB
预演里只剩 tmux 自己(对比 3.2 节的 2 packages)。world 文件两者都不进(依赖不进 world 是 Portage 的基本规则,实测 cat /var/lib/portage/world 无变化)。
3.16 --update / -u:全量升级(-upDN @world)
单个 -u 只升级指定 atom;运维真正用的是组合 -upDN @world:-u 升级、-p 预演、-D(--deep)把依赖树整棵纳入考虑、-N(--newuse)捎带 USE 变化的重编译,@world 覆盖 world + system 全集。实测 emerge -upDN @world --pretend(树刚同步到 2026-10-16、基础系统为 2026-10-11 快照,有真实更新,输出节选):
[ebuild N ] net-libs/ngtcp2-1.25.0 USE="openssl ssl -gnutls -verify-sig" ABI_X86="(64) -32 (-x32)"
[ebuild NS ] dev-build/autoconf-2.73-r2 [2.72-r7]
[ebuild R ] net-misc/curl-8.22.0 USE="http2* http3* quic*"
[ebuild R ] app-crypt/libb2-0.98.1-r3 USE="openmp*"
[ebuild U ] app-crypt/gpgme-2.2.0 [2.1.2]
[ebuild U ] app-arch/libarchive-3.8.10 [3.8.9]
[ebuild U ] dev-build/meson-1.12.1 [1.11.2] PYTHON_TARGETS="(-python3_15)"
[ebuild R ] net-misc/iputils-20250605-r4 USE="filecaps*"
标记速读:N 新依赖、U 升级(方括号是旧版本)、R 重装、NS N+S(slot 变化,新旧 slot 并存)、USE 里的 * 是"标志相对上次构建有变化"——-N 的触发点。确认后去掉 -p 就是真实升级(耗时取决于包量,本文实测环境仅预演留档)。
💡 技术拓展:
@world、@system等"集合(set)"是 emerge 的批量对象——
集合 内容 典型用途 @system profile 定义的系统骨架 极少单独操作 world(selected) 手动显式安装的包(world 文件) -1的对立面,--depclean 的保留名单@world selected + system 的并集 全量升级 -upDN @world@profile 3.16 场景外的其他内置集合 emerge --list-sets全量列出本文实测采用
@world做全量维护;world 文件本体在/var/lib/portage/world,--deselect/--noreplace/-1都在增删这个文件(3.13/3.14/3.19 节实测)。
3.17 --newuse / -N:USE 标志变化触发重编译
-N 让 emerge 把"USE 标志与上次构建不同"的已装包也纳入操作,是 USE 变更后的收尾动作。实测完整闭环:先看当前构建状态(实测 emerge --info app-portage/portage-utils 尾部):
app-portage/portage-utils-0.97.1::gentoo was built with the following:
USE="openmp qmanifest -static" ABI_X86="(64)"
写入包级 USE 关闭 openmp(实测 echo 'app-portage/portage-utils -openmp' > /etc/portage/package.use/nuse-demo),然后 emerge -vN app-portage/portage-utils(输出节选):
--- replaced sym /usr/bin/qatom
--- replaced obj /usr/bin/q
--- replaced dir /usr/bin
--- replaced dir /usr
>>> Original instance of package unmerged safely.
>>> app-portage/portage-utils-0.97.1 merged.
>>> Completed (1 of 1) app-portage/portage-utils-0.97.1::gentoo
-N 检测到 USE 变化触发重编译。验证生效(实测 emerge --info app-portage/portage-utils 尾部):
app-portage/portage-utils-0.97.1::gentoo was built with the following:
USE="qmanifest -openmp -static" ABI_X86="(64)"
-openmp 落地。反向验证:删除 package.use 条目恢复默认,再跑 emerge -vN app-portage/portage-utils(实测输出节选):
>>> Original instance of package unmerged safely.
>>> app-portage/portage-utils-0.97.1 merged.
>>> Completed (1 of 1) app-portage/portage-utils-0.97.1::gentoo
app-portage/portage-utils-0.97.1::gentoo was built with the following:
USE="openmp qmanifest -static" ABI_X86="(64)"
openmp 回到默认启用。两轮重编译期间 q --version 均正常(实测输出 portage-utils-0.97.1),说明该包的 openmp 开关不影响工具可用性——这正是 USE 标志机制的意义:按需裁剪,行为可预期。
⚠️ 注意:不带
-N时,emerge <pkg>对"仅 USE 变化"的已装包也会重装(3.13 节的 R 逻辑);-N的价值在@world级批量——emerge -avN @world一次清完所有 USE 变更。--reinstall changed-use是它的温和版(只对"标志从默认变非默认"的包重编译)。
3.18 --autounmask:keyword 掩码与 USE 冲突的协商
这是 Gentoo 特有且最容易卡新人的机制,本文做了四组实测把行为边界摸清。
第一组:keyword 掩码的报错。 树里的 sys-apps/pv-1.12.0 只带 ~amd64(测试关键字),稳定系统默认看不见它,emerge -pv '=sys-apps/pv-1.12.0' 实测报(3.2 节已留档):masked by: ~amd64 keyword。
第二组:单独 --autounmask-write 的行为。 实测 emerge --autounmask-write -v '=sys-apps/pv-1.12.0':
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.20 s (backtrack: 0/20).
!!! All ebuilds that could satisfy "=sys-apps/pv-1.12.0" have been masked.
!!! One of the following masked packages is required to complete your request:
- sys-apps/pv-1.12.0::gentoo (masked by: ~amd64 keyword)
For more information, see the MASKED PACKAGES section in the emerge
man page or refer to the Gentoo Handbook.
没有任何建议输出,也没有写配置文件——实测确认:在该版 Portage 上 keyword 场景必须显式打开回溯探测。
第三组:三件套触发。 实测 emerge --autounmask=y --autounmask-write --autounmask-backtrack=y -v '=sys-apps/pv-1.12.0':
[ebuild N ~] sys-apps/pv-1.12.0::gentoo USE="ncurses nls -debug -verify-sig" 479 KiB
Total: 1 package (1 new), Size of downloads: 479 KiB
The following keyword changes are necessary to proceed:
(see "package.accept_keywords" in the portage(5) man page for more details)
# required by =sys-apps/pv-1.12.0 (argument)
=sys-apps/pv-1.12.0 ~amd64
Autounmask changes successfully written.
* IMPORTANT: 2 config files in '/etc/portage' need updating.
* See the CONFIGURATION FILES and CONFIGURATION FILES UPDATE TOOLS
* sections of the emerge man page to learn how to update config files.
给出了建议条目 =sys-apps/pv-1.12.0 ~amd64 并报 "successfully written"。但实测发现一个关键细节:此时配置并没有真正生效——紧跟 emerge -pv '=sys-apps/pv-1.12.0' 依然报 masked by: ~amd64 keyword。检查文件现场(实测):
$ ls -la /etc/portage/package.accept_keywords/
-rw-r--r-- 1 root root 97 Oct 17 00:32 ._cfg0000_zz-autounmask
-rw-r--r-- 1 root root 97 Oct 17 00:38 ._cfg0001_zz-autounmask
-rw-r--r-- 1 root root 25 Oct 17 00:32 zz-autounmask
$ cat zz-autounmask
# package.accept_keywords
$ cat ._cfg0000_zz-autounmask
# package.accept_keywords# required by =sys-apps/pv-1.12.0 (argument)
=sys-apps/pv-1.12.0 ~amd64
真相:/etc 在 CONFIG_PROTECT 保护范围内,autounmask 的"写入"被落成了待合并的配置更新文件(._cfg0000_/._cfg0001_ 前缀,每次运行叠一个),真正的条目在暂存文件里,zz-autounmask 本体只有头注释。按 CONFIG_PROTECT 流程应该用 dispatch-conf 合并;实测用等价手工方式应用(mv ._cfg0000_zz-autounmask zz-autounmask),应用后文件内容:
# package.accept_keywords# required by =sys-apps/pv-1.12.0 (argument)
=sys-apps/pv-1.12.0 ~amd64
keyword 立即生效,实测 emerge -pv '=sys-apps/pv-1.12.0':
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.25 s (backtrack: 0/20).
[ebuild N ~] sys-apps/pv-1.12.0::gentoo USE="ncurses nls -debug -verify-sig" 479 KiB
Total: 1 package (1 new), Size of downloads: 479 KiB
从 masked 到 [ebuild N ~],放行链路闭环(3.1 节那台"应答 Yes 后装上 1.12.0"正是踩在这个放行之上)。
第四组:USE 冲突不走 autounmask。 用 package.use 禁掉某标志、再用命令行原子要求它,实测 emerge -pv app-portage/portage-utils[openmp](package.use 已写 app-portage/portage-utils -openmp 时):
These are the packages that would be merged, in order:
Calculating dependencies ... done!
Dependency resolution took 0.26 s (backtrack: 0/20).
emerge: there are no ebuilds built with USE flags to satisfy "app-portage/portage-utils[openmp]".
!!! One of the following packages is required to complete your request:
- app-portage/portage-utils-0.97::gentoo (Change USE: +openmp)
实测加 --autounmask-write 也一样硬报错、不写文件——CLI 原子与配置文件的 USE 冲突要人肉裁决(改 package.use 或去掉内联约束),autounmask 不代办。另一组相关实测:对 profile 默认开启的 qmanifest 用 CLI 原子关闭(emerge -v app-portage/portage-utils[-qmanifest]),实测给出 USE 变更建议并拒绝执行:
The following USE changes are necessary to proceed:
(see "package.use" in the portage(5) man page for more details)
# required by app-portage/portage-utils[-qmanifest] (argument)
>=app-portage/portage-utils-0.97.1 -qmanifest
Use --autounmask-write to write changes to config files (honoring
CONFIG_PROTECT). Carefully examine the list of proposed changes,
paying special attention to mask or keyword changes that may expose
experimental or unstable packages.
💡 技术拓展:Gentoo 的"包不可见/不可装"有三类闸门,解法各不相同——
闸门 报错特征 解法 是否本文实测 keyword 掩码 masked by: ~amd64 keywordpackage.accept_keywords 加 ~amd64(或 autounmask 三件套)是,3.18 第三组 package.mask masked by: package.mask(树方主动遮蔽)谨慎:package.unmask 覆盖 否 USE 冲突 no ebuilds built with USE flags调和 package.use 与原子约束 是,3.18 第四组 本文实测采用 autounmask 三件套处理 keyword、手工调和 package.use 处理 USE;三类闸门中 keyword 掩码最常见(新版本普遍先发
~amd64)。
3.19 --deselect:从 world 移除登记
--deselect 把 atom 从 world 文件里移除,但不卸载包——语义是"不再显式追踪它"。实测 emerge --deselect sys-apps/pv:
>>> Removing sys-apps/pv from "world" favorites file...
world 对照(实测):
$ cat /var/lib/portage/world
app-portage/portage-utils
dev-vcs/git
$ which pv
/usr/sbin/pv
pv 程序还在 /usr/sbin/pv,但已不在 world——之后 --depclean 会把它视为可清理对象(若没有别的包依赖)。典型闭环:emerge --deselect <pkg> → emerge -aC <pkg> → emerge -a --depclean(3.9/3.8 节实测)。
3.20 其余常用参数速查
以下参数在 emerge --help(2.1 节实测全量回显)中列出,本文未逐项展开实测,给出语义速查供索引(用法细节以 man emerge 为准,不编造回显):
| 参数 | 语义 | 与本文实测参数的关系 |
|---|---|---|
| --columns | 对齐 -pv 的列输出 | -pv 的排版变体 |
| --complete-graph / --deep | 扩大依赖图计算范围 | -upDN 组合中的 -D 已实测 |
| --jobs JOBS / --load-average | 并行合并与负载上限 | 多包合并时控制并发 |
| --keep-going | 出错不中断后续包 | 批量升级推荐 |
| --skipfirst | 跳过恢复队列首个包 | 配合 --resume(3.11 节) |
| --color y/n / --nospinner | 关闭彩色与进度动画 | 本文回显均为 --color n --nospinner 实测产物 |
| --reinstall changed-use | -N 的温和版 | 3.17 节已述 |
| --with-bdeps y/n | 构建期依赖是否纳入升级 | -upDN 默认 y |
| --metadata | 重建树元数据缓存 | --sync 后偶发需要 |
| --list-sets | 列出全部集合 | 3.16 节集合体系 |
四、实战示例
4.1 场景一:新装 Gentoo 服务器初始化(内网代理环境标准动作)
目标:一台全新最小系统,从"树为空"到"树最新 + 可正常安装",全部命令实测通过。逐条执行:
第一步,确认版本与网络代理(树缺失时的基线,实测回显见 2.2 节第二段):
export http_proxy=http://192.168.1.62:7897 https_proxy=http://192.168.1.62:7897
emerge --version
第二步,webrsync 引导软件树(走 HTTPS,实测回显见 3.5 节第一步,Total file size: 250.08M bytes):
emerge-webrsync
第三步,裁剪 USE 编译安装 git(实测回显见 3.5 节第二步,git version 2.55.0):
mkdir -p /etc/portage/package.use
cat > /etc/portage/package.use/git <<'EOF'
dev-vcs/git -rust -perl -gpg -webdav -pcre -subversion -tk -highlight -keyring
EOF
emerge -v dev-vcs/git
第四步,git clone 换树并写入常驻 git 同步配置(实测 clone 耗时 9.397 秒、601 MiB、HEAD edf4cb09937ae6320d49052d1a8596e06255c684,配置全文见 3.5 节第三步):
mv /var/db/repos/gentoo /var/db/repos/gentoo.webrsync-bak
git clone --depth 1 https://github.com/gentoo/gentoo.git /var/db/repos/gentoo
rm -rf /var/db/repos/gentoo.webrsync-bak
cat > /etc/portage/repos.conf/gentoo.conf <<'EOF'
[gentoo]
location = /var/db/repos/gentoo
sync-type = git
sync-uri = https://github.com/gentoo/gentoo.git
sync-git-clone-extra-opts = --depth 1
sync-git-fetch-extra-opts = --depth 1
sync-git-verify-commit-signature = false
auto-sync = yes
EOF
第五步,验证同步链路与更新清单(实测回显见 3.5 节 === Sync completed for gentoo 与 3.16 节 -upDN 节选):
emerge --sync
emerge -upDN @world --pretend
验证收尾:emerge --info 的 Head commit of repository gentoo 应为当日提交(3.6 节实测为 edf4cb09937ae6320d49052d1a8596e06255c684),emerge -pv <任意包> 不再报 Invalid Repository Location。
4.2 场景二:日常安装一个新软件(搜索 → 预演 → 确认安装 → 验证)
以安装 pv 为例的完整决策链,全部命令实测。先搜索确认存在与体积(3.4 节实测,Latest version available: 1.10.4、430 KiB);再预演依赖与 USE(3.2 节实测 [ebuild N ]);然后交互安装(3.1 节实测完整生命周期回显);最后验证:
emerge -s '^pv$'
emerge -pv sys-apps/pv
printf 'Yes\n' | script -qec "emerge --color n --nospinner -a sys-apps/pv" /dev/null
pv --version
cat /var/lib/portage/world
实测终态:pv 1.12.0 可用、world 含 sys-apps/pv(3.1 节 J 段实测)。日常人肉操作时省去 script 包装,直接 emerge -a sys-apps/pv 在终端里应答即可。
4.3 场景三:全系统更新 + 孤儿清理闭环
月度维护的标准三段式,全部实测。第一段,同步树(3.5 节实测):
emerge --sync
第二段,预演并执行全量升级(预演回显见 3.16 节;真实执行把 -p 去掉,多包耗时场景按需加 --jobs 2 --keep-going):
emerge -upDN @world --pretend
emerge -avuDN @world
第三段,清理孤儿依赖并复核收敛(3.8 节实测:Number removed: 1 → 复跑 Number removed: 0):
emerge -a --depclean
emerge --depclean
验证收尾:Packages installed 与 Required packages 两数相等(3.8 节实测均为 298),即无孤儿。
4.4 场景四:卸载与 world 瘦身闭环
以"卸掉 tmux 并收走依赖"为例,实测顺序执行:
emerge -pv --depclean app-misc/tmux # 先看反向依赖(3.8 节实测形态)
emerge --deselect app-misc/tmux # 若在 world 中先摘登记(3.19 节实测)
printf 'Yes\n' | script -qec "emerge --color n --nospinner -aC app-misc/tmux" /dev/null # 卸载(3.9 节实测)
printf 'Yes\n' | script -qec "emerge --color n --nospinner -a --depclean" /dev/null # 收孤儿(3.8 节实测,libevent 被移除)
which tmux # 验证(实测:which: no tmux in ...)
实测全过程回显见 3.9/3.19/3.8 节对应段;终态统计 Packages installed: 298 / Number removed: 1。
4.5 场景五:中断恢复与终态体检
长编译被掐断后的救援流程,实测。制造中断与恢复见 3.11 节(kill 后 Exiting on signal 15 → emerge --resume 续完 → tmux -V 验证 tmux 3.6a)。终态体检三件套(全部实测):
$ qlist -I | wc -l
298
$ cat /var/lib/portage/world
app-portage/portage-utils
dev-vcs/git
sys-apps/pv
$ q --version
portage-utils-0.97.1
written for Gentoo by solar, vapier and grobian
qlist -I | wc -l 看装机总量、world 文件看显式集合、q --version 验证 q 系工具链健康——三行即可给一台 Gentoo 服务器做基础画像。
五、注意事项与常见问题
Q1:内网代理环境 emerge --sync 卡死或超时,怎么办?
rsync 协议不吃 http_proxy(3.5 节实测),官方默认的 sync-type = rsync 在这类网络里不可靠。标准方案:先 emerge-webrsync(HTTPS 快照引导出树)→ 裁剪 USE 编译 git → git clone --depth 1 https://github.com/gentoo/gentoo.git /var/db/repos/gentoo → 写 sync-type = git 的 repos.conf。实测全套耗时约 10 分钟(快照下载 + git 编译 + 9.4 秒 clone),之后每次 --sync 只是几秒的 git fetch。注意顺序:先 webrsync 再切 git 配置,反过来 webrsync 会拒绝执行。
Q2:脚本里 emerge -a 报 !!! "--ask" should only be used in a terminal. Exiting.?
--ask 强依赖 tty(实测非终端环境退出码 1,且拒绝发生在依赖解析前,与 pacman 行为完全不同)。脚本去掉 -a(需要幂等加 --noreplace);确实要交互回显时用 printf 'Yes\n' | script -qec "emerge -a <pkg>" /dev/null 分配伪终端(3.1 节实测写法)。
Q3:--autounmask-write 报了 "successfully written",重新 emerge 还是 masked?
/etc 在 CONFIG_PROTECT 保护内,autounmask 的写入落成了 ._cfg0000_ 前缀的待合并配置文件而非直接生效(3.18 节实测:zz-autounmask 本体只有 25 字节头注释,条目在 97 字节的 ._cfg0000_zz-autounmask 里)。用 dispatch-conf 合并(标准做法),或等价地检查 ._cfg* 文件手工应用;应用后 keyword 立即生效(实测从 masked by: ~amd64 keyword 变 [ebuild N ~])。另外实测确认:单独 --autounmask-write 在 keyword 场景下连建议都不给,要 --autounmask=y --autounmask-write --autounmask-backtrack=y 三件套。
Q4:编译安装时刷屏 Unable to unshare: EPERM (for FEATURES="ipc-sandbox network-sandbox pid-sandbox")?
Portage 默认启用三个基于 unshare 的沙箱特性,宿主不允许 unshare 系统调用时每次子进程都会打印该警告(实测在受限环境里一次依赖解析能刷几十行)。真实服务器内核允许 unshare,不会出现。确认为受限环境后可在 make.conf 加 FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox" 关闭(本文实测做法,回显随之干净);代价是失去这三层构建隔离,仅建议在私有构建环境使用。
Q5:照老教程 emerge app-misc/most 报 there are no ebuilds to satisfy?
树是活的,包会下架(app-misc/most 已于实测时点的树中移除,报错还会友好给出 Maybe you meant any of these: app-misc/jot, app-misc/smtm, app-misc/note?)。装任何包前先 emerge -s '^包名$' 确认存在(3.4 节实测),再 -pv 预演。
Q6:git 方案同步的树,怎么确认新旧?有没有 timestamp.chk?
没有。实测 git 树中 /var/db/repos/gentoo/metadata/timestamp.chk 不存在(rsync/webrsync 树才有)。判断新鲜度用 git -C /var/db/repos/gentoo log -1 --format='%H %ci'(实测 edf4cb09937ae6320d49052d1a8596e06255c684 2026-10-16 18:24:56 -0400)或 emerge --info 的 Head commit of repository gentoo 行(3.6 节实测)。
Q7:portage-utils 的 qu 命令找不到?
新版没有 qu(实测 qu 报 command not found),q 系工具清单见 2.3 节实测 ls /usr/bin/q* 共 20 个。常用替代:显式安装集合用 cat /var/lib/portage/world,文件归属用 qfile,包文件清单用 qlist。
Q8:编译时报 Unable to find kernel sources at /usr/src/linux 一堆警告?
这包在探测内核源码(本文实测是 pv,探测 SYSVIPC 以决定是否启用 --remote 功能)。服务器没有装内核源码(sys-kernel/linux-headers 只是头文件)时,这类警告属预期(实测 emerge --info 显示 sys-kernel/linux-headers: 6.18::gentoo (virtual/os-headers)),包仍正常编译安装(3.1 节实测 pv 全流程成功)。只有构建内核模块类包(虚拟化、网卡驱动)才必须先装内核源码。
Q9:-pv 输出里 USE 标志的各种符号什么意思?
无前缀 = 启用;- 前缀 = 关闭;(...) = 被 profile 锁定不可改(如 libevent 的 (-x32));带 * = 与该包上次构建相比有变化(3.3 节实测解读)。Package Settings 段(3.6 节)是"上次构建"的基准,两者对照即可推出 -N 会动谁。
Q10:每次 emerge 都提示 * IMPORTANT: N config files ... need updating?
Portage 对 /etc 下的配置文件改动走 CONFIG_PROTECT:包合并产生的新配置或 autounmask 写入都以 ._cfg0000_* 暂存(Q3),需要 dispatch-conf(推荐,带 diff 与备份)或 etc-update 逐个合并。不处理会一直提示(实测持续出现于后续每次 emerge),处理完即消失。
六、参考链接
- emerge(1) 官方手册(完整参数清单):https://dev.gentoo.org/~zmedico/portage/doc/man/emerge.1.html
- Gentoo Handbook - Working with Portage(emerge 工作流官方教程):https://wiki.gentoo.org/wiki/Handbook:AMD64/Portage/Tools
- Gentoo Wiki - Emerge(参数与技巧):https://wiki.gentoo.org/wiki/Emerge
- Gentoo Wiki - Portage(体系与配置总览):https://wiki.gentoo.org/wiki/Portage
- Gentoo Wiki - Portage-utils(q 系工具集):https://wiki.gentoo.org/wiki/Portage-utils
- 官方包搜索(packages.gentoo.org,查看 keyword/USE 全景):https://packages.gentoo.org/
- Portage 软件树 git 仓库(git 同步方案的 sync-uri):https://github.com/gentoo/gentoo
- Gentoo 手册本地查阅:
man emerge、man portage、man make.conf、man 5 ebuild