misOrz

IT Tech & Life

NixOS vs Ubuntu:差異比較與適合的使用者

一句話定位

很多人問我該選 NixOS 還是 Ubuntu。先講結論:這兩個系統的哲學完全不同,選哪個取決於你想怎麼「管」一台電腦,而不是哪個比較強。

  • Ubuntu:最成熟、最好上手的通用 Linux 發行版,裝好就能用。
  • NixOS:整個系統用一份設定檔宣告出來的 Linux,改設定、升級、回滾全部可重現。

核心差異對照

項目UbuntuNixOS
系統設定方式各處設定檔+指令,改完就生效全部寫進 configuration.nix,改完要 nixos-rebuild switch 才生效
套件管理apt(.deb)+ SnapNix(nixpkgs,超過 8 萬個套件)
升級與回滾升級出問題要手動修復原子升級,開機選單可直接回到上一個世代(generation)
套件隔離全域共用函式庫,依賴衝突較常見每個套件獨立放在 /nix/store,多版本可共存
發行週期半年一版、兩年一個 LTS,LTS 標準支援 5 年(26.04 LTS 支援到 2031 年 5 月)每半年一版(目前最新 26.05),單一版本支援約 7 個月
學習曲線低,文件與教學最多高,要學 Nix 語言與模組系統
硬體與商業軟體最好,筆電驅動、閉源軟體支援最完整較弱,閉源驅動與商業軟體要額外處理
商業支援Canonical 提供 Ubuntu Pro、企業支援與認證以社群為主,無同等級商業支援

NixOS 最大的不同:系統即設定檔

NixOS logo

NixOS 標誌,CC BY 4.0 授權(出處:NixOS 官方品牌頁,授權條款)

在 NixOS,裝了什麼軟體、開了什麼服務、系統長什麼樣子,全部寫在設定檔裡。換一台機器時,把設定檔複製過去、跑一次重建,就能得到幾乎一樣的系統;設定檔還能放進 Git 版控,哪天改壞了直接回到上一個版本。這也是為什麼它在開發環境與伺服器佈署上特別受歡迎。

代價就是門檻:Nix 語言與模組寫法一開始不好上手,遇到問題時,網路上的解法也比 Ubuntu 少很多。

Ubuntu 最大的優勢:生態與省心

Ubuntu logo

Ubuntu Circle of Friends 標誌 © Canonical Ltd.(GPL-3.0);Ubuntu 為 Canonical Ltd. 的註冊商標

Ubuntu 是最多人用的 Linux 桌面與伺服器發行版之一,遇到問題幾乎都找得到現成答案。筆電 Wi-Fi、顯示卡驅動、印表機、商業軟體的相容性通常是最好的;企業環境還能買 Canonical 的支援與 Ubuntu Pro 的延長安全更新。缺點是系統狀態是「長」出來的:裝久了、改多了,出問題時很難說清楚當初改了什麼,也很難完整複製到另一台機器。

適合的使用者

選 NixOS,如果你是:

  • 開發者,想讓開發環境完全可重現,換機器不用重配
  • SRE/DevOps,想把伺服器設定版控化、多台機器保持一致
  • 喜歡折騰、願意花時間學新工具,換取長期維護的輕鬆
  • 需要同一軟體多版本共存(例如多個 Python、Node 版本互不干擾)

選 Ubuntu,如果你是:

  • Linux 新手,或只想裝好就專心工作
  • 企業、生產環境,需要商業支援、認證與長期安全更新
  • 筆電主力機,硬體相容與閉源驅動優先
  • 團隊協作,需要大家用同一套標準環境

折衷方案

不一定要二選一:在 Ubuntu 上也可以只裝 Nix 套件管理器,享受宣告式開發環境(home-manager、flake),系統本體仍維持 Ubuntu 的省心;反過來也可以先在虛擬機裡玩 NixOS,習慣了再決定要不要當主力。

結語

想要「裝好就不用管」選 Ubuntu;想要「系統狀態全部寫在設定檔裡、可以重現」選 NixOS。我的建議是:主力工作機先用 Ubuntu,需要可重現環境時再把 Nix 引進來,兩邊的好處都拿得到。

xtool: build and deploy iOS apps without Xcode

Found this while looking into iOS build options: xtool is a cross-platform Xcode replacement — it builds a SwiftPM package into an iOS app on Linux, WSL, macOS, and Windows.

What it covers:

  • Build a SwiftPM package into an iOS app
  • Sign and install iOS apps (xtool install xxx.ipa, xtool devices, xtool launch)
  • Apple Developer Services via CLI (xtool auth, xtool ds) and as a library (XKit SwiftPM product)

Handy subcommands:

xtool new      # create a new xtool SwiftPM project
xtool dev      # build and run it (screenshot below: Ubuntu + VSCode → iPhone)
xtool devices  # list devices

Why I bookmarked it: my day-to-day dev machine is Linux/Android. If I ever want an iOS companion for my QRCode scan app without buying into the full Xcode workflow, this is the kind of tool that makes it plausible — SwiftPM in, signed ipa out, no Mac required (per its README).

Screenshot from the xtool repo (VSCode on Ubuntu running xtool dev → installing to an iPhone):

Screenshot of xtool running in VSCode on Ubuntu, installing to an iPhone
Screenshot from the xtool repo — © 2024 Kabir Oberai, MIT License


Reference: https://github.com/xtool-org/xtool

Fix TTS init failure on Xiaomi (MIUI): declare TTS_SERVICE in the AndroidManifest queries block

Symptom: In my QRCode scan app, TextToSpeech init failed on a Xiaomi phone (China MIUI ROM) — status=-1 for engine com.google.android.tts, completely silent. The same APK worked fine on a Realme phone.

What I ruled out first:

  • Media volume was on, in-app TTS toggle was on.
  • Xiaomi's "Text-to-speech output": preferred engine was Google TTS, language Chinese (Taiwan), and the system "Listen to an example" test played sound fine — the engine itself was healthy.
  • Explicitly specifying Google TTS and adding an engine fallback list both failed the same way (system default was already Google, nothing to fall back to).

Root cause: Android 11+ package visibility. Since API 30, an app cannot see — and therefore cannot bind — another app's service unless it declares the intent in <queries>. Google TTS is a third-party app providing a TTS service; without the declaration, binding the TTS engine is silently blocked and TextToSpeech init returns ERROR (-1). Some OEM ROMs (e.g. Realme) don't enforce this strictly, which is why the same APK worked there.

Fix — add to AndroidManifest.xml:

<queries>
    <intent>
        <action android:name="android.intent.action.TTS_SERVICE" />
    </intent>
</queries>

After adding this (shipped as v1.1), TTS worked on both Xiaomi and Realme.

Lesson: whenever your app binds a service provided by another app (TTS engine, etc.) on Android 11+, declare the matching <queries> entry — otherwise the bind fails silently on strict OEM ROMs.


 

Create VLANs in Linux

 

ip link add link eth0 name eth0.3001 type vlan id 3001

ip addr add 192.168.100.1/24 brd 192.168.100.255 dev eth0.3001

ip link set dev eth0.3001 up

ip -d addr show



Reference: https://www.baeldung.com/linux/vlans-create





Login as Root in Ubuntu GUI

GDM – GNOME Display Manager

/etc/pam.d/gdm-autologin

/etc/pam.d/gdm-password

註解掉 # auth required pam_succeed_if.so user != root quiet_success

sudo service gdm restart





How to connect hidden ssid on debian 11

root@LINUX:~# rfkill unblock wifi

root@LINUX:~# killall wpa_supplicant

root@LINUX:~# wpa_passphrase SSID-NAME Password > wpa.conf

root@LINUX:~# wpa_supplicant -i wlan0 -c wpa.conf -B

root@LINUX:~# dhclient wlan0





changed its 'Version' value from '11.5' to '11.8'

 N: Repository 'http://opensource.nchc.org.tw/debian bullseye InRelease' changed its 'Version' value from '11.5' to '11.8'


root@LINUX:~/tmp# apt-get update --allow-releaseinfo-change