外观
Ubuntu 开机后第一次打开终端很慢的排查与修复
最近遇到一个现象:Ubuntu 开机并登录桌面后,第一次打开 GNOME Terminal 会很慢,大约需要 20 多秒;但终端窗口打开以后,再关闭并重新打开,就会变得很快。
这个问题一开始看起来像是 shell 启动脚本太慢,例如 ~/.bashrc 中加载了 nvm、conda、补全脚本或者执行了图形相关命令。但实际排查后发现,主要问题不在 bash,而是在 GNOME Terminal 冷启动时依赖的用户级 portal 服务。
先确认不是 shell 启动慢
可以先测试 bash 本身的启动时间:
/usr/bin/time -f 'bash_login_elapsed=%e' bash -lic 'exit'
/usr/bin/time -f 'bash_nonlogin_elapsed=%e' bash -ic 'exit'这次测试里,两个结果都只有约 0.2s:
bash_login_elapsed=0.24
bash_nonlogin_elapsed=0.22所以 20 多秒的等待不是 ~/.bashrc 整体造成的。
不过还是发现了一个不太合适的配置:~/.bashrc 里有这一行:
setxkbmap -option caps:swapescape这类 X11 键盘设置不适合放在 ~/.bashrc,因为每次打开终端都会执行一次。更推荐放到桌面环境的键盘设置、GNOME Tweaks,或者图形会话启动项里。
查看用户服务日志
真正有用的信息来自用户级 systemd 日志:
journalctl --user -b \
-u xdg-desktop-portal.service \
-u xdg-desktop-portal-gnome.service \
-u xdg-desktop-portal-gtk.service \
-u gnome-terminal-server.service \
--no-pager日志里可以看到非常明显的时间线:
09:11:15 Starting gnome-terminal-server.service - GNOME Terminal Server...
09:11:41 Started gnome-terminal-server.service - GNOME Terminal Server.也就是说,GNOME Terminal Server 从开始启动到完成用了大约 26s,这正好对应第一次打开终端时的等待时间。
同时,在它之前还能看到 xdg-desktop-portal 相关超时:
Failed to create settings proxy:
为 org.freedesktop.impl.portal.desktop.gnome 调用 StartServiceByName 时出错:已到超时限制
Failed to create file chooser proxy:
为 org.freedesktop.impl.portal.desktop.gnome 调用 StartServiceByName 时出错:已到超时限制
xdg-desktop-portal.service: start operation timed out.这说明第一次开终端时,gnome-terminal-server 的冷启动被 xdg-desktop-portal / xdg-desktop-portal-gnome 的 D-Bus 超时拖住了。等这些服务成功启动以后,后续再打开终端就只是在复用已经运行的 gnome-terminal-server,所以会很快。
手动重启 portal 服务
可以先手动重启相关用户服务:
systemctl --user restart \
xdg-desktop-portal.service \
xdg-desktop-portal-gnome.service \
xdg-desktop-portal-gtk.service然后检查状态:
systemctl --user status \
xdg-desktop-portal.service \
xdg-desktop-portal-gnome.service \
xdg-desktop-portal-gtk.service \
--no-pager正常情况下应该看到三个服务都是:
active (running)这次手动重启的结果是成功的,退出码为 0,并且三个服务都处于 active (running) 状态。重启耗时不到 1 秒,没有再次出现 25 秒左右的 D-Bus 超时。
日志里只剩一个小警告:
Unknown key gtk-modules in /home/wugs/.config/gtk-4.0/settings.ini这个警告表示 GTK4 不认识 gtk-modules 这个配置项,不是第一次打开终端很慢的主因。
用 systemd 用户服务做开机预热
为了避免每次登录后第一次打开终端才触发 portal 冷启动,可以写一个用户级 systemd 服务,在图形会话启动后主动预热 portal。
文件路径:
~/.config/systemd/user/portal-warmup.service内容如下:
[Unit]
Description=Warm up xdg-desktop-portal after graphical session starts
After=graphical-session.target
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --user restart xdg-desktop-portal.service xdg-desktop-portal-gnome.service xdg-desktop-portal-gtk.service
[Install]
WantedBy=graphical-session.target这里的关键点是:
After=graphical-session.target:等图形会话启动后再执行。Type=oneshot:这是一次性任务,执行完就退出,不是常驻服务。ExecStart=... restart ...:主动重启并拉起 portal 相关服务。WantedBy=graphical-session.target:让它随图形会话自动运行。
启用这个服务:
systemctl --user daemon-reload
systemctl --user enable portal-warmup.service如果想马上手动执行一次:
systemctl --user start portal-warmup.service查看状态:
systemctl --user status portal-warmup.service --no-pager如果看到类似下面的结果,说明它执行成功:
Loaded: loaded (.../portal-warmup.service; enabled)
Active: inactive (dead)
ExecStart=... status=0/SUCCESS
Finished portal-warmup.service这里的 inactive (dead) 是正常的,因为 portal-warmup.service 是 Type=oneshot,执行完预热命令后就会退出。判断是否成功要看 status=0/SUCCESS 和 Finished portal-warmup.service。
查看日志:
journalctl --user -u portal-warmup.service -b --no-pager如果修改了 service 文件
每次修改 ~/.config/systemd/user/portal-warmup.service 后,都需要重新加载用户级 systemd 配置:
systemctl --user daemon-reload然后可以重新执行一次:
systemctl --user restart portal-warmup.service总结
这个问题的根因是:
- 第一次打开 GNOME Terminal 时,需要冷启动
gnome-terminal-server.service。 - 冷启动过程中,
xdg-desktop-portal尝试调用xdg-desktop-portal-gnome。 - 这个调用发生了 D-Bus 超时,导致终端第一次启动被拖慢到 20 多秒。
- 后续再打开终端时,
gnome-terminal-server已经在后台运行,所以速度恢复正常。
解决思路是:
- 手动重启
xdg-desktop-portal相关用户服务,可以立即恢复当前会话。 - 使用
portal-warmup.service在图形会话启动后提前预热 portal,避免第一次打开终端时才触发慢启动。
版权所有
版权归属:Guisong Wu