Linux 上的 GNU sed 與 macOS 內的 sed 的 in-place 差異

結論:用 Perl

寫 shell script 的時候遇到的問題,在 Linux 上面使用 sed 換檔案裡面的字串,但不想要產生 backup file 的方式是:

sed -i -e 's/foo/bar/' example.txt

但在 macOS 內建的 sed 則是:

sed -i '' -e 's/foo/bar/' example.txt

也就是說前者 GNU sed 是處理 $1 (argv[1],anyway) 後面貼著的參數,而後者 macOS 的則是吃 $2 (argv[2]) 的參數。

Stack Overflow 上的「sed in-place flag that works both on Mac (BSD) and Linux」這邊有討論,看起來 sed 上沒有通解。

翻了 The Open Group 上的說明,sed 應該是定義在 POSIX 裡面,而從文件裡面沒有提到 backup file 可以知道這是各家自己實作的功能:「sed」。

所以一種解法是用 detection 的方式針對不同的 sed 給不同的指令;而另外一種解法是找其他工具。後者考慮到普及性,用 Perl 應該會是比較好的方式,目前不是 minimal 類的系統應該都還有 Perl 可以用:

perl -pi -e 's/foo/bar/' example.txt

但這樣跑在 CI 裡面的時候就得小心一點了,如果選到 minimal image 的話就會中獎... (煩躁?)

OpenBSD 提供了關閉 Nagle's algorithm 的 sysctl 選項

看到「Demise of Nagle's algorithm (RFC 896 - Congestion Control) predicted via sysctl」這篇,OpenBSD 提供 sysctl 的選項直接關閉 Nagle's algorithm

The below changeset introduces sysctl net.inet.tcp.nodelay, which if set to 1 will simply cause TCP_NODELAY to be set on all TCP sockets.

不過裡面提到了 John Nagle 在 2015 年的時候有在 Hacker News 上面回覆 (id=10608356),大概介紹了一下背景,以及提出了他的看法:

That still irks me. The real problem is not tinygram prevention. It's ACK delays, and that stupid fixed timer. They both went into TCP around the same time, but independently. I did tinygram prevention (the Nagle algorithm) and Berkeley did delayed ACKs, both in the early 1980s. The combination of the two is awful. Unfortunately by the time I found about delayed ACKs, I had changed jobs, was out of networking, and doing a product for Autodesk on non-networked PCs.

然後翻了一下 John Nagle 的 Hacker News 帳號,看起來還蠻活躍的?常常 comment 一些東西...

Ubuntu 的 LTS 從 10 年變成 12 年

積了一個多月的東西,Canonical 宣佈 UbuntuLTS 從 10 年變成 12 年 (付費版本):「Canonical expands Long Term Support to 12 years starting with Ubuntu 14.04 LTS」,這個改變會包括 (三月當時) 快要滿十年的 14.04 (trusty) 以及之後的版本:

Today, Canonical announced the general availability of Legacy Support, an Ubuntu Pro add-on that expands security and support coverage for Ubuntu LTS releases to 12 years. The add-on will be available for Ubuntu 14.04 LTS onwards.

應該是被不少既有客戶要求後發現有市場,所以就決定先延個兩年看看?

寫這篇才意外注意到 Ubuntu 14.04 到現在也已經十年了,這幾天在看 Travis CI 的資料,發現這個平台支援一堆古董,可以看到 Ubuntu 12.04 (precise) 的 image,而且最新也才支援到 Ubuntu 20.04 (focal):「Build Environment Overview」。

MIT license 與 Expat license

在包新版的 dehydrated 時發現 license 的部分過不去,說沒有 mit 這個選項:

dh_make: error: argument -c/--copyright: invalid choice: 'mit' (choose from 'apache', 'artistic', 'bsd', 'gpl', 'gpl2', 'gpl3', 'isc', 'lgpl', 'lgpl2', 'lgpl3', 'expat', 'custom')

翻了程式碼也的確是被拔掉了,先從 manpage 上確認,可以看到在 20.04 上面還有看到 mit,但到了 22.04 上面就沒看到了:「focal (1) dh_make.1.gz」與「jammy (1) dh_make.1.gz」。

回到上游去找可以翻到「Rename MIT license to Expat Closes: #963141」這個 commit,裡面提到的票在「Debian Bug report logs - #963141 /usr/bin/dh_make: "MIT" license should be called Expat to be more specific」這個 bug report 可以看到。

維基百科上面的「MIT License」有提到一些名稱背景:

The MIT License has the identifier MIT in the SPDX License List. It is also known as the "Expat License".

看起來主要是避免誤會,不過我自己覺得是不太容易誤會,但反正就改了:

The name "MIT License" is potentially ambiguous. The Massachusetts Institute of Technology has used many licenses for software since its creation[.]

當初 22.04 的 package 好像是直接在網站上點一點 copy 出來的,所以沒遇到這個問題...

MS-DOS v4.0 的程式碼以 MIT license 釋出

Hacker News 上的消息「Open Sourcing DOS 4 (hanselman.com)」,原文在「Open Sourcing DOS 4」。

Hacker News 裡面的討論有拉出一些有趣的 source code 註解,不過我比較好奇為什麼是挑 v4.0 而不是其他版本,看說明應該是剛好遇到對的人與對的團體?

A young English researcher named Connor "Starfrost" Hyde recently corresponded with former Microsoft Chief Technical Officer Ray Ozzie about some of the software in his collection. Amongst the floppies, Ray found unreleased beta binaries of DOS 4.0 that he was sent while he was at Lotus. Starfrost reached out to the Microsoft Open Source Programs Office (OSPO) to explore releasing DOS 4 source, as he is working on documenting the relationship between DOS 4, MT-DOS, and what would eventually become OS/2. Some later versions of these Multitasking DOS binaries can be found around the internet, but these new Ozzie beta binaries appear to be much earlier, unreleased, and also include the ibmbio.com source.

這些程式碼主要都是考古分析用了,不知道什麼時候 MS-DOS 6.22 的 code 會冒出來...

在 virt-manager 裡面的 Windows 發出聲音

用了幾個月才發現沒聲音,花了點時間找方法測試才解決。

一般人用預設值應該是沒問題,不過我的環境比較特別,剛好不是預設值,我的 PulseAudio 輸出到 DA&T C-13 時是設定成 96kHz/24bit,而一般 Windows 預設輸出時是 44.1kHz/16bit,兩邊對不起來就沒聲音了。

找了一些文章,後來是在「Virtual machine audio setup – or how to get pulse audio working」這篇裡面講到用 virsh 直接改 XML 設定檔的方式讓 qemu 輸出到 PulseAudio 裡面轉,也就是文章裡面 Option 2 的部分。

這樣 guest OS 裡面還是跑 44.1/16,但外面輸出的時候就固定是 96/24 了。

比較奇怪的是如果 guest 裡面跑 96/16 的話聲音會破破的,不過我只是要有聲音 (不然也不會用了好幾個月才發現),品質的問題倒是還好...

Windows 98 安裝的三階段

看到「Why does part of the Windows 98 Setup program look older than the rest? (2020) (retrocomputing.stackexchange.com)」這個,原文是 2020 的討論:「Why does part of the Windows 98 Setup program look older than the rest?」。

問題是 Windows 98 的安裝過程中段可以看出來有 Windows 3.1 介面的感覺,像這樣:

而到了後段又是 Windows 98 的感覺,作者覺得 UI 介面風格不一致的問題...

回答的人則是解釋得很清楚,第一階段是 DOS 階段,會把 Windows 3.1 環境疊出來:

The first, which can run from the setup floppies and/or CD-ROM, uses a DOS program (DOSSETUP.BIN) to set up disk partitions, run various checks etc.:

This phases finishes by copying a minimal version of Windows 3.1 to the target installation drive, in a temporary directory (normally WININST0.400), containing DOSX.EXE, USER.EXE, GDI.EXE, KRNL386.EXE, LZEXPAND.DLL etc. (see MINI.CAB).

第二階段則是 Windows 3.1 環境,把 Windows 98 大多數的東西都複製到硬碟上:

The second uses this minimal Windows 3.1 to run a Windows 3 program, W98SETUP.BIN (specified as the “shell” in SYSTEM.INI):

This starts by copying more files to support all the information-gathering during setup, and various other niceties including the 3D look shown in your screenshot (the contents of the PRECOPY CABs); it ends by copying most of Windows 98, setting the system up so that it will boot Windows 98 from the target drive, and rebooting.

第三階段則是 Windows 98 環境,執行後續的設定程式:

The third runs after the first boot into Windows 98, from Windows 98:

而且也提到了當年可以升級作業系統的情況 (雖然我自己偏好重裝):

It is also possible to initiate the setup process from any of the above environments, which is how Windows 98 handles upgrades (from MS-DOS, or Windows 3, or Windows 95).

是個解釋遺跡的現場 XDDD

Brendan Gregg 推薦平常在 Linux 上先裝好的工具

Brendan Gregg 推薦了一整包內建的工具 (透過系統的 apt repository 就能裝),平常先準備好,出問題的時候可以直接拿出來用:「Linux Crisis Tools」。

作者有提到表上列出來的工具算是基本盤,有特殊硬體的情況 (像是 GPU) 需要再加裝其他的套件:

This list is a minimum. Some servers have accelerators and you'll want their analysis tools installed as well: e.g., on Intel GPU servers, the intel-gpu-tools package; on NVIDIA, nvidia-smi. Debugging tools, like gdb(1), can also be pre-installed for immediate use in a crisis.

這邊是把表格有提到的都放進去,另外包括了上面提到的 GDB

sudo apt install -y bpfcc-tools bpftrace cpuid ethtool gdb iproute2 linux-tools-common msr-tools nicstat numactl procps sysstat tcpdump tiptop trace-cmd util-linux; sudo apt clean

裝了以後可以順便拿這張表格練練手,把不熟悉的工具開 backlog 找機會練手,熟悉一下這些工具的常用用法,這樣遇到狀況的時候可以直接用...

syllazh:拿同音字硬顯示到 Linux TTY 的 console 上面

翻資料的時候翻到用 Python 寫的 syllazh 這個東西,可以在 Linux TTY console 上面直接顯示中文,我本來以為是類似 big5con 的東西,看了一下完全不是,syllazh 是直接透過 Linux TTY 搞,所以會受限於 512 字的限制,而 big5con 是切進圖形模式自己處理,所以可以完整顯示 big5 上面的字:

Linux TTY 上的字体可以由一般位于kbd软件包里的setfont工具更换。它最多支持512个字形(glyph),但每个字形可以被映射到多个 Unicode 码位。 所以为了支持显示中文,我必须把成千上万个汉字挤进这个狭小的空间。 幸运的是,现代汉语普通话大约只有400个不同的音节(忽略声调)。于是我针对每个音节,挑选了一个最常用的汉字来代表那最多上百个读音近似的汉字。 这样再加上96个可见的ASCII字符和几个符号,它们就正好装进512字符的限制内了!

然後這邊因為不可能將所有的中文字都塞進去,syllazh 的作法就是找同音字塞,效果就會變成這樣:

這主要還是好玩為主,作者自己也有提到這點:

老实讲,盯着这些同音错字并通过句子来费劲猜测它是什么意思,并不是很愉快的体验。因此我也不期待任何人日常使用它。 现在都2024年了,你应该去用你喜欢的 Wayland 或 X 桌面,而不是TTY。所有主要的图形界面库对中文(以及所有其他语言)的支持都比我这奇技淫巧高到不知哪里去了。

從 VirtualBox 換到 virt-manager

為了可以使用 KVM,把桌機 Ubuntu (Xubuntu) 上的 VM 都從 VirtualBox 換到 virt-manager 了...

不得不說 VirtualBox 包的很好,很多事情就不用自己繞半天... 在 virt-manager 上面有蠻多東西得自己設定繞開,把 2024 年會遇到的問題整理下來。

首先是權限的部分,裝完 virt-manager 後馬上打開會遇到 virt-manager 說連不到 libvirtd 的問題:「virt-manager can't connect to libvirt」,而最簡單的解法就是重開機,原因是安裝過程中在 /etc/group 增加了 libvirt 的權限,現有的 session 因為權限不夠無法連上 libvirtd。

接下來就是操作介面上的順暢度問題了,預設「Automatically detect from the installation media / source」是勾起來的,但你丟 Windows 的 ISO 進去不一定會偵測到是 Windows 的 ISO,需要把勾勾拿掉,然後自己輸入 win 後才會出現可以選的選項,而不是直接選單選擇... 這邊的 UX 在第一次用的時候還蠻卡的。

另外裡面設定也是有問題的,選擇 Windows XP 會發現網路的設定居然還是用 e1000,導致 Windows XP 抓不到網路卡,需要另外再改成 rtl8139 (不過速度只有 100Mbps)。

最後在 Network selection 的部分,NAT 算是最常用的,不過如果要自己架設 lab 的話 (像是我弄了三台 Ubuntu VM 測各種服務),直覺會設定成 Bridge device,但這邊的 Bridge device 是需要先自己設定好 bridge interface 後再讓 virt-manager 設定掛進去。

所以比較「簡單」的方式 (當時以為比較簡單) 是選擇 Macvtap,然後選擇要用的介面,這樣設定後主機的確可以透過指定的介面連到 Internet 上,但就像設定 Macvtap 時出現的警告,guest 與 host 本機之間是無法溝通的:「In most configuration, macvtap does not work for host to guest network communication.」。

解決的方法還是自己搞 bridge interface,這邊由於 Ubuntu 現在網路都是透過 Netplan 在管理,我是透過「[Wishlist] Support macvlan/macvtap interfaces」這邊提供的 workaround 來解決。

以前是直接在 enps0f0 上面設定 IP address,現在是在 networkd 跑起來就先建立 macvlan0,然後在上面設定 IP address。然後 virt-manager 就可以用 macvtap 到 macvlan0 了,實際測試 guest 與 host 之間也通了...

折騰了一會算是搬過來了,這樣總算是可以在桌機上面跑 android emulator 了,先前硬關掉 KVM 跑了兩次,速度實在是受不了,就跑去 Mac 上開發了,現在這樣好多了...