ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ubuntu 18.04终端打不开?从locale到D-Bus排查

Ubuntu 18.04终端打不开?从locale到D-Bus排查 Ubuntu 18.04 到现在还有一大批人在用——工控机、老笔记本、实验室的采集主机、嵌入式开发板甚至一些产线上还在跑的设备都长期停在 18.04。它的长期支持周期早已结束很多团队之所以不升级是因为手上的工具链、驱动、还有那套 autoware 相机雷达联合标定工具只在 18.04 上验证过动一次就得重新调一轮谁都不愿意。系统用得越久被折腾过的地方就越多于是有个毛病出现的频率高得离谱点左上角的 Terminal 图标鼠标转两圈没了按 CtrlAltT桌面抖一下什么也不弹。有时候连系统设置、右键菜单里的部分功能也开始迟钝。这个问题的难受之处在于时间点特别尴尬——你正打算进终端去修别的东西结果终端自己先躺了。终端本来是排查系统的入口入口没了等于钥匙锁在车里。网上搜一圈答案高度雷同重装 gnome-terminal。可真正动手的人会发现重装完它照样打不开因为根因往往根本不在终端这个程序身上你把窗户修得再结实门锁坏了你还是进不去。所以这篇不打算只丢三条命令草草收场。我把这些年踩过的坑捋一遍先讲清楚终端到底是怎么被拉起来的再看它通常在哪一步断掉最后给出一套不依赖终端就能完整跑通的排查与修复流程。刚从 18.04 安装教程里走出来的新手还是被这问题折磨过好几回的老手都能从这里拿到可以直接照着敲的方案。全文涉及的命令我都实机验证过风险高的地方会单独标出来。1. 终端打不开先定位它卡在哪一层1.1 三种典型表现对应完全不同的病因很多人一上来就说终端打不开但这四个字背后其实至少有三种截然不同的画面先把它们区分开排查效率能翻好几倍。第一种是点图标或者按快捷键后完全没反应任务栏上连个影子都没有ps里也看不到 gnome-terminal 相关的进程。这种多半是环境变量、locale 或者启动脚本在源头就把进程干掉或者干卡住了程序根本没跑起来。第二种是窗口闪一下就消失你可能瞥见一个黑框转瞬没了。这类通常是 gnome-terminal 客户端进程成功启动了但它在跟 gnome-terminal-server 建立连接的过程中失败然后自行退出。错误信息通常写在.xsession-errors或者 journal 里不在屏幕上。第三种是窗口出现了但一直转圈标题栏显示Terminal却永远白屏最后弹一个超时。这种最常见的原因反而是 gnome-terminal-server 进程本身卡死了——它是个后台常驻进程管理所有终端窗口一旦它状态异常新开的窗口就全被它拖住。注意这三种情况对应的修复命令完全不一样。上来就无脑重装等于三种病吃同一种药运气好碰对一种运气差全白干。1.2 为什么偏偏是 Ubuntu 18.04 容易出这个问题新装好的 18.04 其实很少出这毛病出问题的几乎都是被用了一阵子的系统。原因集中在几个方向上。一是 18.04 的桌面是 GNOME 3.28而它的终端组件从更早就改成了客户端 后台服务的架构客户端只是个瘦壳子真正的窗口由 gnome-terminal-server 通过 D-Bus 管理。这套架构比老的单体终端更依赖系统服务状态系统里任何一环D-Bus、locale、会话管理器出问题终端都跟着遭殃。二是 18.04 系统自带的 Python 是 3.6而大量工具、脚本、甚至某些系统组件都依赖/usr/bin/python3。很多人在这个版本上装 Anaconda、换 Python 版本、或者干脆把/usr/bin/python3指向了自己编译的新版本直接把系统层面依赖 Python 的东西一起带崩。三是这个版本老了系统里被 apt 装过、卸过、改过的东西太多环境变量、locale、PATH 这些看不见的配置很容易被某次误操作污染而它们恰恰是终端启动时最先读取的东西。1.3 从启动链路看清终端是怎么被拉起来的想修得准得知道正常流程长什么样。你在桌面点终端图标链路大致是这样的图标先调用/usr/bin/gnome-terminal这其实是个 shell 脚本脚本会做几件事——检查 locale、设置一些环境变量、然后尝试连接 D-Bus 会话总线上的 gnome-terminal-server如果 server 不在它就用dbus-launch或 systemd 用户会话把它拉起来server 起来后接受请求创建窗口、加载 VTE 库、渲染终端界面。这条链上任何一环断了你看到的就是打不开。链子前段脚本、locale、环境变量出问题表现为完全没反应中段D-Bus、server 连接出问题表现为闪退或超时后段VTE 渲染、显卡驱动出问题表现为窗口出来了但是黑屏、花屏。记住这条链路后面的排查就是沿着它从前往后捋。2. 按优先级把常见根因一个个排掉2.1 locale 配置损坏——这是最高频的元凶我经手的终端打不开里大概四成到最后都指向 locale。表现很典型从 TTY 单独手动运行 gnome-terminal 时会看到类似Failed to set locale, defaulting to C的警告或者干脆报一个跟setlocale有关的错误然后退出。locale 为什么会坏常见来源有几个图省事用export LANGxxx写进了.bashrc或/etc/environment但对应的 locale 根本没有生成从别的机器拷过来的配置文件带了宿主机没有的 locale或者某次系统更新把 locale 数据包弄得不完整。判断方法很简单在 TTY 里敲locale和locale -a看当前LANG、LC_ALL指向的语言是不是在已生成列表里。如果LANG指向zh_CN.UTF-8但locale -a里只有C和POSIX那基本可以确定问题就在这。2.2 Python 环境被改动前面提过18.04 深度依赖系统 Python。典型翻车场景是你为了跑某个标定脚本装了 Anaconda或者在/usr/bin下把python3软链到了自己编译的版本又或者手贱执行了sudo apt remove python3。结果系统里那些靠 Python 写的脚本和小工具开始全线崩溃某些启动流程卡在 Python 调用上终端启动链路也跟着断。判断方法在 TTY 里敲python3 --version和which python3。如果版本对不上 3.6或者路径指向了/opt/anaconda、/usr/local/bin之类那就得小心了尤其要检查/usr/bin/python3这个软链有没有被改。2.3 PATH 与环境变量被写坏.bashrc、.profile、/etc/environment、/etc/profile.d/下的脚本是环境变量污染的四大高发区。有人在这几个地方写了export PATH自己的路径把系统路径覆盖掉了有人写了带语法错误的语句导致整个登录 shell 卡住还有人写了export TERMxxx指向一个不存在的终端类型。TERM这个变量特别容易被忽略。终端程序启动时会读TERM来决定用什么能力集去渲染如果它被设成了一个系统里没有 terminfo 定义的值终端可能起来就报错闪退。判断方法从 TTY 里敲echo $PATH、echo $TERM跟默认值对比。默认TERM一般是xterm-256color或linuxPATH 里应该有/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin这一串。2.4 后台 server 卡死或渲染问题如果前面三项都正常那就往 D-Bus 和 gnome-terminal-server 方向查。最常见的是 server 进程假死——它没退出但也不响应任何请求新窗口全部超时。这种在ps aux | grep gnome-terminal里能看到一个状态异常的gnome-terminal-server。另一类是渲染后端的问题。18.04 的 GNOME 默认走 Wayland但很多老显卡驱动在 Wayland 下不稳定切换回 Xorg 有时就能好。终端窗口黑屏、花屏多半和 VTE 库调用底层渲染有关显卡驱动更新过之后尤其容易出现。2.5 权限与磁盘空间还有两个容易被忽略的地雷一是$HOME或者~/.config目录的属主被改成了 root导致普通用户打开终端时写配置失败而崩溃二是$HOME所在分区或者/tmp被写满终端启动时需要写临时文件和 socket写不进去自然起不来。判断方法df -h看各分区空间ls -ld ~ ~/.config看属主。这两个检查花不了十秒钟但能省下你半小时的瞎折腾。3. 不依赖终端怎么把系统修回来3.1 第一步钻进 TTY拿到一个能敲命令的地方终端打不开但你还有更底层的入口——TTY虚拟控制台。在图形界面下按CtrlAltF3F1 到 F6 都行会切到一个纯文本登录界面输入用户名和密码就能进去。这里没有图形界面但能敲任何命令是修系统的急救通道。进去之后先别急着修把当前登录 shell 的环境摸一遍这几条命令几乎是每次都要跑的echo $LANG echo $PATH echo $TERM locale locale -a df -h ls -ld ~ ~/.config提示如果切到 TTY 后屏幕全黑没反应试试CtrlAltF7或者CtrlAltF1、CtrlAltF2不同显卡驱动分给图形界面的 TTY 编号不一样多试两个就能找到。3.2 修复 locale最干净的做法确认是 locale 问题后别急着到处改环境变量最干净的是把标准 locale 重新生成一遍sudo apt install --reinstall locales sudo dpkg-reconfigure localesdpkg-reconfigure locales会弹出一个列表勾选你需要用的语言比如en_US.UTF-8和zh_CN.UTF-8然后设一个默认的。跑完之后再locale -a确认一下目标语言是否出现在列表里。如果不想进交互界面也可以用命令直接生成sudo locale-gen en_US.UTF-8 sudo locale-gen zh_CN.UTF-8 sudo update-locale LANGen_US.UTF-8这里我一般建议先把LANG设成en_US.UTF-8因为英文环境最不容易出编码相关的幺蛾子。等终端恢复了再考虑要不要切回中文。3.3 顺手检查.bashrc和.profile里的可疑语句locale 修完接着看家目录下的启动脚本。这两个文件每次开 shell 都会被读一遍里面任何一句错误的export都可能把终端启动搞挂。我的习惯是先临时把它们挪开看看终端能不能起来mv ~/.bashrc ~/.bashrc.bak mv ~/.profile ~/.profile.bak挪完之后回到图形界面CtrlAltF7之类再试着打开终端。如果能开了说明锅就在这两个文件里接下来就是逐行往回找。找的时候重点看这几类export LANG、export LC_ALL、export PATH、export TERM、以及任何看起来像自己加上去的赋值的语句。把我自己那份被污染过的.bashrc拿出来对比的例子——有一回我图省事写了export LC_ALLzh_CN.UTF-8但那台机器上根本没生成这个 locale结果就是这个文件一被读取所有新开的 shell 全部报 locale 警告。删掉这一行终端立马恢复正常。系统级别的四个文件也一并检查/etc/environment、/etc/profile、/etc/profile.d/下的脚本、还有~/.xsessionrc。改动前记得先备份。3.4 修复被改动的 Python 环境如果which python3指向的不是/usr/bin/python3先想办法还原。最稳的做法是重新建立软链ls -l /usr/bin/python3 sudo ln -sf /usr/bin/python3.6 /usr/bin/python3如果/usr/bin/python3.6本身都被删了那就用 apt 把它装回来sudo apt install --reinstall python3.6 python3.6-minimal sudo ln -sf /usr/bin/python3.6 /usr/bin/python3注意这一步风险不低。如果/usr/bin/python3被指向了一个你自己编译的 3.9 或者 Anaconda 里的版本很多系统工具比如apt的某些模块、gnome-terminal依赖的software-properties会直接报语法错误或者导入失败。所以任何改动/usr/bin/python3的操作动手前都想清楚。装 Anaconda 请务必让它只改用户 PATH不要覆盖系统解释器。3.5 处理 server 卡死与渲染问题前面几项都排除了就把目标转向后台进程。从 TTY 里先把 gnome-terminal-server 干净地清掉killall gnome-terminal-server killall gnome-terminal如果killall提示找不到进程说明是另一个问题看第 3.3 节的脚本污染。清完之后回到图形界面重开终端。如果还是转圈或者超时可以更进一步把 D-Bus 会话相关的用户服务重启一下systemctl --user restart dbus.service这一步会重置当前图形会话的 D-Bus可能会让已开的图形程序掉线动手前存好没保存的东西。如果是渲染问题黑屏、花屏可以在登录界面点齿轮图标把会话从 Wayland 切到 Xorg或者在/etc/gdm3/custom.conf里把#WaylandEnablefalse那行前面的注释去掉重启后生效。4. 几类真实现场案例与命令实录4.1 案例一locale 缺失导致窗口一闪而过现场一台用了两年的 18.04 台式机终端图标能点窗口一闪就没。系统里没装过 Anaconda也没改过 Python。排查切 TTY敲locale输出里LANG后面是空的locale -a只有C、POSIX、C.UTF-8。再手动跑/usr/bin/gnome-terminal屏幕上刷出一行warning: setlocale: LC_ALL: cannot change locale。根因用户之前为了显示中文在.bashrc里写了export LC_ALLzh_CN.UTF-8但这台机器从没生成过这个 locale被读取后 GNOME 组件解析环境变量时出错。处置sudo locale-gen zh_CN.UTF-8 sudo update-locale LANGzh_CN.UTF-8 # 或者干脆先设成 en_US.UTF-8 更稳跑完切回图形界面终端恢复。4.2 案例二卸载了系统 Python图形终端彻底没了现场开发者为了搞定环境冲突执行了sudo apt remove python3桌面当场开始出问题重启后终端、设置面板、软件中心全部打不开。排查TTY 里which python3返回空ls /usr/bin/python3*什么都没有apt本身也开始报错。根因18.04 的系统 Python 被整个铲掉了大量系统组件依赖它apt 依赖链也跟着崩。处置这一步比较麻烦因为 apt 自己也坏了。先把最基础的包重新装回去sudo apt install --reinstall python3-minimal python3.6-minimal python3 sudo apt install --reinstall gnome-terminal sudo apt install --reinstall ubuntu-desktop这里有个小窍门如果 apt 报 Python 相关的错误可以先用sudo dpkg -i手动安装从别处拷过来的.deb包或者用/usr/bin/python3.6的完整路径去跑那些卡住的脚本。实操心得这就是我一直劝人别在系统盘上随便动/usr/bin/python3的原因。想要独立 Python 环境用 venv 或者 conda 的用户级安装别碰系统解释器。4.3 案例三PATH 被覆盖所有命令都找不到现场同事改.profile时不小心把export PATH...写成了覆盖而不是追加把系统路径整个冲掉了。排查TTY 里echo $PATH只显示他自己加的一条路径ls、cd这些命令都用不了得用/bin/ls这样的绝对路径才能跑。根因PATH 被覆盖系统找不到常用命令终端启动脚本里的命令调用全部失败。处置直接用绝对路径改文件/usr/bin/vi ~/.profile把那一行改回追加写法export PATH$PATH:/你自己的路径记住正确的姿势永远是PATH$PATH:新路径追加而不是等号右边直接写新路径。这一步改错的人真的太多了。4.4 案例四显卡驱动更新后终端黑屏现场更新完 NVIDIA 驱动重启后终端窗口能开但内容区全黑打字也看不到。排查TTY 正常说明系统本身没问题。切到 Xorg 会话后终端显示正常。根因新驱动在 Wayland 下与 VTE 库的渲染路径不兼容。处置登录界面切 Xorg 会话或者保险起见直接关掉 Waylandsudo vi /etc/gdm3/custom.conf # 取消注释WaylandEnablefalse sudo systemctl restart gdm35. 速查表与避坑清单5.1 症状、根因、处置对照表症状表现最可能根因优先排查命令点图标完全无反应locale 缺失 / 脚本污染locale、locale -a、检查.bashrc窗口一闪而过Python 环境被改 / 启动脚本报错which python3、手动跑gnome-terminal窗口转圈超时gnome-terminal-server 卡死ps aux、killall gnome-terminal-server所有命令找不到PATH 被覆盖echo $PATH、用绝对路径改.profile窗口黑屏花屏显卡驱动 / Wayland 兼容切 Xorg、WaylandEnablefalse桌面整体卡顿磁盘写满 / 目录属主错误df -h、ls -ld ~ ~/.config5.2 我最想让人避开的几个坑第一个坑是无脑重装 gnome-terminal。绝大多数情况下重装根本解决不了因为锅不在终端程序本身重装只是把启动链路的最后一段刷新了一遍前面断的地方照样断。第二个坑是在系统层面改.bashrc和/etc/environment来优化环境。这些文件是全局生效的写错一行的代价是整个图形会话起不来。改之前一定要备份改完立刻在 TTY 里验证一遍新开的 shell 有没有报错。第三个坑是把 Python 系统解释器当玩具。18.04 的系统组件对/usr/bin/python3的依赖比你想象的深很多看起来跟 Python 八竿子打不着的程序其实底层都在调用它。第四个坑是忽略日志。.xsession-errors和journalctl --user -xe里经常明明白白写着失败原因但大多数人一上来就切 TTY 盲敲命令绕一大圈才发现日志里那行报错。5.3 日常维护的几条建议把这套排查流程顺手存到手机备忘录里下次出问题直接对照省得临时搜索。平时改动系统配置前养成备份习惯.bashrc、.profile、/etc/environment改动前先cp一份带日期后缀的副本。系统更新前确保$HOME和/tmp有充足空间别在小分区上硬扛。如果你的设备要长期停在 18.04装完所有驱动和工具后做一个完整镜像备份出事了直接恢复比现场抢修靠谱得多。最后分享一个我压箱底的小技巧。当你不确定终端到底是启动链路哪一环断了的时候在 TTY 里用这条命令直接手动拉起图形终端看它往屏幕上吐什么DISPLAY:0 gnome-terminalDISPLAY:0让这个命令把窗口画到当前图形会话上如果失败它会把真实的错误信息直接打印在你面前比看日志猜要快得多。我这些年遇到的终端故障十有八九都是靠这一条命令当场定位的。
返回列表