2025 年末,我将日常办公的笔记本电脑系统切换到了 Arch Linux 上。

建议先从缘起开始阅读。日后谈为后续遇到的一些问题与解决方案。

日后谈

2025-12-13

Paru

第一次用到 Timeshift,在 sudo pacman -Syyu 之后遇到

paru: error while loading shared libraries: libalpm.so.15: cannot open shared object file: No such file or directory

正好是周末没怎么用电脑,吓得我赶紧回滚。看了一下 Arch 群组发现大家都炸了,paru 的 issue 里也有 Support for libalpm v16.0.0 #1454

WPS Office

WPS-Office 有无法输入中文的问题,在修复WPS Office的Fcitx5输入法问题中包含解决方案,包括评论区也有通过 pacman hook 解决的,我这里选择不用 aur 的源,还是用 nix 去搞,我编写了一段配置文件,解决创建新文档与无法输入中文这两个问题,见 WPS Office Home Manager 配置文件

它做的事情很简单,一是自定义图标,二是将 WPS 自带的一些模板放到 Templates 里面。


缘起

切换到 Linux 的想法很简单:有一天我突然发现我的工作和日常完全不需要 Windows 了,打开 Windows 之后我的第一步是打开 Windows Terminal 连接 WSL,然后在纯粹的 WSL 上办公。而我又少有需要 Office 全家桶的需求,再加上 Windows 自作主张地推送各种 AI 功能,我自然而然地想到了抛弃 Windows。至于打游戏?感觉现在打开 Steam 的次数少得可怜,偶尔玩一玩米家三件套,用一台 Windows 台式机专门打游戏就好啦。

图源:https://www.linkedin.com/posts/manivannanpalanichamy_no-offence-microsoft-but-this-meme-killed-activity-7204737792923357184-H3gZ

那么,选择什么样的操作系统呢?Ubuntu 24.04 比较成熟,但 snap 我是拒绝的;Nix OS 看上去很 cool,但需要自己考虑包的编译和使用,我觉得我是没那么多精力去折腾了。MacOS?饶了我吧……看了一圈之后,我打算在 Debian 13、Arch Linux 和 Fedora 之间抉择。在咨询身边使用 Linux 的朋友的体验,以及考虑到社区的规模之后,我选择了 Arch Linux 作为主力系统。

图源:https://devrant.com/rants/2123557/thats-a-new-one

切换

我并非没有 Arch Linux 的使用经验。在老笔记本上我尝试过一段时间 Manjaro,也配置过 i3 wm 等界面。最后是因为需要打游戏+一些常用软件使用起来并不是很顺畅才换回 Windows。而 2025 年大部分的国产程序因为要支持信创,对 Linux 的支持变好了很多,即使无法在 Arch 上运行也能在 Ubuntu 上运行,这样我们就可以用各种方式创造在 Arch 上运行的条件。

现在从头开始安装 Arch 的教程有很多,笔者在此就不多加描述了。个人推荐 https://arch.icekylin.online/ 这一款,我参考该教程完成了安装。

简单介绍一下自己选择的一些应用及原因:

桌面环境我选择了 KDE Plasma,它目前是少数几个默认使用 Wayland 而不是 X11 的 DE 之一,且我对它的好感要大于 Gnome。为什么不选择 WM 呢?一是要由用户排布窗口布局,GUI 程序一多还是会到处浮动。而对于 CLI 界面,我习惯 Yakuake + Zellij 开启多个窗口,更是没有用 WM 的必要。为了减少心智负担,以及确实没那么多时间折腾界面,KDE 就是最好的归宿了。

图源:https://imgflip.com/i/a2n3s2

KDE 上一些惊喜的点在于:

  1. 多显示器管理完美。可以同步更改所有显示器的亮度,也可以快速修改键盘背光亮度;
    • 但是如果一台显示器同时接了多个主机的话,即使当前显示器显示的并不是 Arch 的界面,也可能会因为种种原因(例如睡眠)被修改亮度;
  2. 大量好用的可选插件,例如下拉式终端 Yakuake、KDE connect、Krdc 等等;
    • Spectacle 录制屏幕简单方便,生成的文件极小,强烈安利!
  3. KDE 中的语言配置不会影响到 tty;
    • 我之前担心 KDE 设置语言会影响到全局 locale,但是学弟告诉我并不会,在修改之后发现确实如此,太棒了!

输入法我选择了 fcitx5 + 雾凇拼音,这一套很多人都推荐过。虽然没有云拼音在最新词汇上有点缺乏,但日用还是足够了。至于软件适配……就只能见招拆招了,参考 Arch Wiki 以及论坛上的帖子进行适配,实在不行就到 Arch 群组中呼唤大佬吧~

管理

在使用一段时间后,我发现 Arch 包的依赖较为复杂:有时候安装一个包要引入大量依赖,而卸载包时因为各种相关依赖不能一口气全卸载掉。虽然 pacman -Qtdq 命令可以检查孤立依赖包,但总是比较费事,万一依赖出问题或者更新问题导致系统挂了就麻烦了。有些时候我想用的包会用到比较旧的库,CLI 的话有 docker 无所谓,但 GUI 的话就比较麻烦了。有没有一种方式能自动管理这些依赖库,由我自己控制库版本呢?在整理现有条件及要求后,我认为 Nix 包管理器是最适合当前的情况的。

图源:https://x.com/archlinuxmemes/status/1286728740244819968

看到这张图片的 Arch 用户,请立刻执行 sudo pacman -Syyu

之前没有用 NixOS 作为操作系统很简单,我没有使用经验,NixOS 默认不遵循 FHS 标准而我有使用闭源二进制的需求,我没时间自己打包也不想从头学 Nix 的各种语法。不过 Nix 可以作为与其他系统默认包管理不冲突的包管理器安装,这让我对它产生了兴趣。

我对 Nix 提出的可复现性很感兴趣:在日常使用中,这台电脑基本上只有我一个用户,因此使用 Nix + home manager 管理个人用户的程序和配置就是我全部的需求了。这正好是 Nix 的长处。我参考 https://determinate.systems/ 上的教程在 Arch 上安装了 Nix 相关的程序,并使用 flake 进行管理。

图源:https://www.reddit.com/r/NixOS/comments/1bfc9tm/meme_nixos_infection/

我之前曾经担心过使用 Nix 运行 CLI 无法调用显卡的问题,也确实遇到了安装 zeditor 之后无法打开的情况。在一番搜索后,我发现 Home Manager 已经为我们解决了这个问题:从 Home Manager 25.11 起内置了 non-nixos-gpu,只需要添加 targets.genericLinux.enable = true; 再更新就可以收到需要执行的命令的提示了,非常完美~

以 qq 为例,想要使用 fcitx5 输入法时需要加入 --ozone-platform-hint=auto --enable-wayland-ime 参数,我们可以在 KDE 的菜单中修改桌面项。但使用了 Nix 之后,我们可以直接在配置文件中修改,更新后(可能需要注销重新登录)即可同步到所有快捷方式上:

hosts/username/home.nix
  xdg.desktopEntries = {
    qq = {
      name = "QQ";
      genericName = "Instant Messaging";
      # https://forum.archlinuxcn.org/t/topic/13464/27
      # 添加 --ozone-platform-hint=auto --enable-wayland-ime
      exec = "${pkgs.qq}/bin/qq --ozone-platform-hint=auto --enable-wayland-ime %U";
      terminal = false;
      categories = [
        "Network"
        "InstantMessaging"
      ];
      icon = "qq";
      comment = "QQ for Linux";
    };
  };

实际上,Nix 也确实解决了我遇到的一些问题。在使用 pacman 安装 syncplay 时,我遇到了 qt 库缺失的问题导致无法启动 GUI,只能通过 CLI 操作,而换用 Nix 之后则一切正常。这让我回想起切换到 Arch Linux 之初遇到的问题:公司的国产 Electron IM “只”支持统信 UOS 和麒麟 V10(当然也能在 Ubuntu 上运行),在 Arch 上即使通过 debtap 进行重打包,也会出现库太新导致的种种问题,这种情况下,是否能用 Nix 进行打包呢?

当然可以!在参考 NixOS 系列(三):软件打包,从入门到放弃这篇文章后,我部署了 NixOS 虚拟机,在 Gemini 的帮助下进行打包。一段漫长的经历后,我用 steam-run 的方式跑了起来,但悲伤的是非 NixOS 环境下 steam-run 有一些问题,只能采用 autoPatchelfHook 的方式进行打包。不过反复 battle 后还是成功打出了可用的包,呱唧呱唧~

图源:https://t.me/addstickers/ur_dumb

我也创建了自己的 nur 源,目前只维护了上面所说的这一个包。如果有同学遇到了和我一样的依赖旧版库的闭源二进制打包问题的话可以参考。如果想要使用该包的话,可以在 flake.nix 中导入源并添加 overlay。这是我目前的 flake.nix:

flake.nix
{
  description = "...";
 
  inputs = {
    # 指定 nixpkgs 的版本,这里使用 unstable 分支
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
 
    # Home Manager 的源
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
 
    qrzbing = {
      url = "github:qrzbing/nur-packages";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
 
  outputs =
    {
      nixpkgs,
      home-manager,
      qrzbing,
      ...
    }@inputs:
    let
      system = "x86_64-linux"; # Arch 绝大多数情况是 x86_64-linux
      pkgs = import nixpkgs {
        inherit system;
        # 允许非自由软件 (解决 firefox-bin, vscode 等报错)
        config.allowUnfree = true;
        overlays = [
          (final: prev: {
            # 将你的仓库注入到 pkgs.qrzbing 下
            qrzbing = qrzbing.packages.${system};
          })
        ];
      };
    in
    {
      homeConfigurations = {
        "username@host" = home-manager.lib.homeManagerConfiguration {
          inherit pkgs;
 
          extraSpecialArgs = { inherit inputs; };
 
          # 指向该主机的特定入口文件
          modules = [ ./hosts/username/home.nix ];
        };
      };
    };
}
 

之后在 home.nix 中添加该包,为了使 fcitx5 能够工作,我们还需要覆写图标等信息:

hosts/username/home.nix
{
  config,
  pkgs,
  inputs,
  ...
}:
 
{
  #...
 
  home.packages = with pkgs; [
    #...
    qrzbing.lanxin # 蓝信
  ];
 
  targets.genericLinux.enable = true;
  xdg.enable = true;
  xdg.mime.enable = true;
 
  xdg.desktopEntries = {
    #...
 
    lanxin = {
      name = "蓝信";
      genericName = "Instant Messaging";
      comment = "蓝信-安全数智化工作平台";
      icon = "lanxin";
 
      exec = "env XMODIFIERS=\"@im=fcitx\" GTK_IM_MODULE=\"fcitx\" QT_IM_MODULE=\"fcitx\" SDL_IM_MODULE=fcitx GLFW_IM_MODULE=ibus ${pkgs.qrzbing.lanxin}/bin/lanxin %U";
 
      terminal = false;
      categories = [
        "Network"
        "InstantMessaging"
        "Chat"
      ];
    };
  };
  #...
}

说实话,这种通过配置文件管理软件包的感觉确实很爽,有种一切尽在掌握的感觉。尽管如此,我还是不想切换到 NixOS,什么时候我将 pacman 管理的库全部掏空再考虑吧。

除此之外,Nix 用来管理字体也很不错。我的字体配置参考为:

{ pkgs, ... }:
 
{
  home.packages = with pkgs; [
    # 安装字体
    ## nerd-fonts: 编程字体与 yazi 支持
    nerd-fonts.fira-code
    nerd-fonts.droid-sans-mono
 
    ## 中文/日文/韩文 现代字体
    noto-fonts-cjk-sans # 思源黑体
    noto-fonts-cjk-serif # 思源宋体
    noto-fonts-color-emoji # 表情符号
    sarasa-gothic # 更纱黑体 https://zhuanlan.zhihu.com/p/627059922
 
    # 备用字体 (解决部分软件乱码)
    wqy_zenhei # 文泉驿正黑
    wqy_microhei # 文泉驿微米黑
  ];
 
  # 字体管理
  fonts.fontconfig = {
    enable = true;
    # fc-list : family | grep Math 查看字体类型
    defaultFonts = {
      # 等宽字体 (终端/编辑器用)
      monospace = [
        "FiraCode Nerd Font Mono"
        "Noto Sans Mono CJK SC"
        "DejaVu Sans Mono"
      ];
 
      # 无衬线字体 (系统界面/网页主要用)
      sansSerif = [
        "Sarasa Gothic SC"
        "WenQuanYi Micro Hei"
        "DejaVu Sans"
      ];
 
      # 衬线字体 (文档/阅读用)
      # 更纱黑体没有 serif
      serif = [
        "Noto Serif CJK SC"
        "WenQuanYi Zen Hei Sharp"
        "DejaVu Serif"
      ];
 
      # Emoji 字体
      emoji = [ "Noto Color Emoji" ];
    };
  };
}

我让这一套配置接管了 Arch 的字体配置,手写 xml 什么的,实在是做不来啦~

问题

当然,我现在还遇到了一些未能解决的问题,在此也做个记录。

  • Wayland 和 tun 冲突,我经常需要创建 tun 网卡(也包含开机启动),在此问题能自动化解决之前暂时不考虑安装 Wayland。
  • 腾讯会议的共享桌面时好时坏,社区中也提到过这个问题
  • 米家三件套国服版自带反作弊器,经常遇到无法运行(4001)的问题。不过考虑到 780M 这个集显性能也就那样,还是用台式机打游戏/串流吧。
  • 微信截图有奇怪的问题,如果操作太快的话遮罩会完全覆盖屏幕且无法退出,只能切换到 tty kill 掉进程。
  • Chromium 会触发 AMD GPU 的崩溃,虽然只遇到了两次但我一共也只有这两次卡住的经历。

小结

10 月 25 日切换到 Arch Linux 以来,我已经高强度使用 Arch Linux 办公一月有余了。不敢说自己有多么深入 Arch 的使用,但总的来说确实体验很棒。Arch Linux 和 NixOS 的社群都很友善,在使用过程中虽然遇到过一些问题,但在社群伙伴的帮助下都得到了解决。欢迎更多的小伙伴加入 Arch Linux 的大家庭哦~

附录

WPS Office Home Manager 配置文件

{ pkgs, lib, ... }:
 
let
  # 定义通用的环境变量前缀,WPS 通常运行在 XWayland 下,这些变量对 Fcitx 是必须的
  wpsEnv = "env XMODIFIERS=\"@im=fcitx\" GTK_IM_MODULE=\"fcitx\" QT_IM_MODULE=\"fcitx\" SDL_IM_MODULE=fcitx";
  # WPS 模板配置文件路径
  wpsTemplates = "${pkgs.wpsoffice-cn}/opt/kingsoft/wps-office/office6/asso_template";
in
{
  targets.genericLinux.enable = true;
  xdg.enable = true;
 
  home.activation.copyWpsTemplates = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
    run mkdir -p $HOME/Templates
 
    verboseEcho "Copying WPS templates to ~/Templates..."
 
    run install -m 644 "${wpsTemplates}/wps.docx" "$HOME/Templates/新建 Word 文档.docx"
    run install -m 644 "${wpsTemplates}/wps.xlsx" "$HOME/Templates/新建 Excel 工作表.xlsx"
    run install -m 644 "${wpsTemplates}/wps.pptx" "$HOME/Templates/新建 PPT 演示文稿.pptx"
  '';
 
  xdg.desktopEntries = {
    wps-office-wps = {
      name = "WPS 文字";
      genericName = "Word Processor";
      comment = "WPS Office Writer";
      exec = "${wpsEnv} ${pkgs.wpsoffice-cn}/bin/wps %F";
      icon = "wps-office-wpsmain";
      terminal = false;
      categories = [
        "Office"
        "WordProcessor"
      ];
      mimeType = [
        "application/msword"
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        "application/rtf"
        "text/rtf"
      ];
    };
 
    wps-office-et = {
      name = "WPS 表格";
      genericName = "Spreadsheet";
      comment = "WPS Office Spreadsheets";
      exec = "${wpsEnv} ${pkgs.wpsoffice-cn}/bin/et %F";
      icon = "wps-office-etmain";
      terminal = false;
      categories = [
        "Office"
        "Spreadsheet"
      ];
      mimeType = [
        "application/vnd.ms-excel"
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        "text/csv"
      ];
    };
 
    wps-office-wpp = {
      name = "WPS 演示";
      genericName = "Presentation";
      comment = "WPS Office Presentation";
      exec = "${wpsEnv} ${pkgs.wpsoffice-cn}/bin/wpp %F";
      icon = "wps-office-wppmain";
      terminal = false;
      categories = [
        "Office"
        "Presentation"
      ];
      mimeType = [
        "application/vnd.ms-powerpoint"
        "application/vnd.openxmlformats-officedocument.presentationml.presentation"
      ];
    };
 
    wps-office-pdf = {
      name = "WPS PDF";
      genericName = "PDF Reader";
      exec = "${wpsEnv} ${pkgs.wpsoffice-cn}/bin/wpspdf %F";
      icon = "wps-office2023-pdfmain";
      terminal = false;
      categories = [
        "Office"
      ];
      mimeType = [ "application/pdf" ];
    };
  };
}