用 jc 將常見的 CLI 指令輸出轉成 JSON 或是 YAML

看到「kellyjonbrazil/jc」這個專案,展試一下就可以理解用途了:(最後接 jq 只是為了 pretty print)

$ dig www.google.com | jc --dig | jq
[
  {
    "id": 57567,
    "opcode": "QUERY",
    "status": "NOERROR",
    "flags": [
      "qr",
      "rd",
      "ra"
    ],
    "query_num": 1,
    "answer_num": 1,
    "authority_num": 0,
    "additional_num": 1,
    "opt_pseudosection": {
      "edns": {
        "version": 0,
        "flags": [],
        "udp": 1232
      },
      "cookie": "37fe52c319e24fbbeadce09b6579665ea173fcd360d0a298"
    },
    "question": {
      "name": "www.google.com.",
      "class": "IN",
      "type": "A"
    },
    "answer": [
      {
        "name": "www.google.com.",
        "class": "IN",
        "type": "A",
        "ttl": 249,
        "data": "142.251.42.228"
      }
    ],
    "query_time": 0,
    "server": "168.95.192.1#53(168.95.192.1) (UDP)",
    "when": "Wed Dec 13 16:07:58 CST 2023",
    "rcvd": 87,
    "when_epoch": 1702454878,
    "when_epoch_utc": null
  }
]

覺得可以開始用的原因是發現從 Ubuntu 22.04 開始,在官方的 APT repository 有把 jc 包進去了,裝起來會簡單不少。

雖然 22.04 裡面包的版本是 1.17.3 (現在是 1.23.6),但這個版本已經支援不少格式了。

之後在 shell script 裡面自己 grep + sed 組到起笑的時候,可以考慮加掛 jc + jq 的組合技來解決,不過缺點就是要額外裝...

FreeBSD 14.0 釋出

FreeBSD 14.0-RELEASE 的公告也出來了:「FreeBSD 14.0-RELEASE Announcement」,比較完整的 release notes 在「FreeBSD 14.0-RELEASE Release Notes」。

先從官方列的 highlight 來看,首先比較重要的是 GENERIC kernel 支援 1024 cores:

FreeBSD supports up to 1024 cores on the amd64 and arm64 platforms.

看了一下 commit log 是從 256 變成 1024

先就 x86-64 這邊來看,目前「家用」最多的應該是 AMD7995WX (96 cores),舊版的 256 限制應該也還能撐住,但看 commit log 有提到,主要是預期這幾年應該會有更暴力的機器出現。

另外一塊是伺服器端,Intel 這邊有 8 sockets 的版本 (參考「Intel Xeon Sapphire Rapids to Scale to 4 and 8 Sockets」),如果都是接 8490H 的話就是 480 cores 了。

ARM 的話好像也可以堆,但不熟...

另外一個提到的重點是 TCP 預設的 congestion control 改成 CUBIC

The default congestion control mechanism for TCP is now CUBIC.

翻 commit log 可以看到是從 NewReno 換成 CUBIC 的,這樣就跟 Linux kernel 預設值一樣了。

再來比較重要的是在 release notes 裡面提到的,FreeBSD 15.0 將會拔光 32-bit 環境的支援,只留 armv7,這代表 Raspberry Pi 第一代的 armv6 也被淘汰掉了:

FreeBSD 15.0 is not expected to include support for 32-bit platforms other than armv7. The armv6, i386, and powerpc platforms are deprecated and will be removed. 64-bit systems will still be able to run older 32-bit binaries.

然後有些我自己翻覺得還蠻有趣的。

首先是看到 non-root 的 chroot

The chroot facility supports unprivileged operation, and the chroot(8) program has a -n option to enable its use. a40cf4175c90 (Sponsored by EPSRC)

然後把 OpenSSH 內對 FIDO/U2F 的支援開起來了:

The use of FIDO/U2F hardware authenticators has been enabled in ssh, using the new public key types ecdsa-sk and ed25519-sk, along with corresponding certificate types. FIDO/U2F support is described in https://www.openssh.com/txt/release-8.2. e9a994639b2a (Sponsored by The FreeBSD Foundation)

ASLR 預設開啟:

Address Space Layout Randomization (ASLR) is enabled for 64-bit executables by default. It can be disabled as needed if applications fail unexpectedly, for example with segmentation faults. To disable for a single invocation, use the proccontrol(1) command: proccontrol -m aslr -s disable command. To disable ASLR for all invocations of a binary, use the elfctl(1) command: elfctl -e +noaslr file. Problems should be reported via the problem reporting system, https://bugs.freebsd.org, or posting to the freebsd-stable@FreeBSD.org mailing list. b014e0f15bc7 (Sponsored by Stormshield)

然後先前被罵臭頭的 WireGuard 支援也放回來了:(「FreeBSD & pfSense 上的 WireGuard 問題」)

The kernel wg(4) WireGuard driver has been reintegrated; it provides Virtual Private Network (VPN) interfaces using the WireGuard protocol. 744bfb213144 (Sponsored by Rubicon Communications, LLC ("Netgate") and The FreeBSD Foundation)

然後看到 Netflix 贊助的 kTLS 支援 TLS 1.3:

KTLS (the kernel TLS implementation) has added receive offload support for TLS 1.3. Receive offload is now supported for TLS 1.1 through 1.3; send offload is supported for TLS 1.0 through 1.3. 05a1d0f5d7ac (Sponsored by Netflix)

然後 FreeBSD 長久以來 root 預設用的 /bin/csh 改成 /bin/sh 了:

The default shell for the root user is now sh(1), which has many new features for interactive use. d410b585b6f0

預設的 MTA 變成 dma (Dragonfly Mail Agent),看名字加上翻了一下 manpage,確認是從 Dragonfly BSD 移植過來的:

The default mail transport agent (MTA) is now the Dragonfly Mail Agent (dma(8)) rather than sendmail(8). Configuration of the MTA is done via mailer.conf(5). sendmail(8) and its configuration remain available. a67b925ff3e5

然後 portsnap 被拔掉了,現在就建議直接用 git 拉了,算是功成身退了:

The portsnap(8) utility has been removed. Users are encouraged to fetch the ports tree by using pkg install git and then git clone https://git.FreeBSD.org/ports.git /usr/ports. df53ae0fdd98

而 mergemaster 也被換成 etcupdate 了:

mergemaster(8) has been deprecated. Its replacement is etcupdate(8). 398b12691b4f (Sponsored by The FreeBSD Foundation)

然後支援 tarfs,而且可以用 zstd

The tarfs(5) file system has been added, which is backed by POSIX tar archives optionally compressed with zstd(1). 69d94f4c7608 (Sponsored by Juniper Networks, Inc.) (Sponsored by Klara, Inc.)

好久沒看 FreeBSD 的 release notes...

用 try 來看檔案系統的改變

Hacker News Daily 上看到這則:「Try: run a command and inspect its effects before changing your live system (github.com/binpash)」,這是一個 GitHub 專案:「binpash/try」。

整包軟體意外的簡單,是一隻 shell script,透過 OverlayFS 取得改變的部分:

try lets you run a command and inspect its effects before changing your live system. try uses Linux's namespaces (via unshare) and the overlayfs union filesystem.

記得 OverlayFS 在 Docker 用的很多,所以穩定性應該是沒什麼問題,不過專案開頭也有提到,這只是把 filesystem 層拆出來,不是很嚴謹的 sandbox 環境,像是 /dev 這邊的東西還是有穿透性,不要跑不信任的程式:

Please note that try is a prototype and not a full sandbox, and should not be used to execute commands that you don't already trust on your system, (i.e. devices in /dev are mounted in the sandbox, and network calls are all allowed.) Please do not attempt any commands that will remove everything in /dev or write zeros to your disks.

我覺得這個很適合拿來跑各種 install.sh 這種東西?有些 install.sh 不知道塞了多少垃圾 (像是 .bashrc 或是 .profile 都有可能會被動),可以知道有哪些檔案要清會比較好。

把裡面的 try 這個檔案丟到自己的可執行目錄就裝好了,像是 ~/.local/bin 或是 ~/bin 之類的地方,看你的 $PATH 設定決定。

另外也可以從 subcommands 裡面的指令看到你可以用 try explore 啟動 shell 跑進去看:

Subcommands:
  try summary DIR   show the summary for the overlay in DIR
  try commit DIR    commit the overlay in DIR
  try explore DIR   start a shell inside the overlay in DIR

GitHub 上面的範例是用 pip 示範,同樣道理應該也可以看 npm 與其他套件。

純 POSIX sh 實作各種功能

看到「pure sh bible」這篇,講純 POSIX 的 sh 可以怎麼實作各種功能,Hacker News 上的討論在「Pure Sh Bible (github.com/dylanaraps)」這邊。

一般我在寫 cross platform 的 shell script 時候會假設是 POSIX environment,而不是只有 POSIX sh 硬扛,所以還是有 awkgrepsed 這類工具可以用... 而這篇裡面提到的方法有些很明顯是硬扛過去的 XD

不過裡面還是有些章節是應該要熟悉的,像是對 string 的處理算是蠻好用的,不需要拿 sed 出來用。

另外可以用 bash 的話,有很多東西會好寫很多,但開頭的 #!/bin/bashFreeBSD 上會因為 bash 會裝到 /usr/local/bin/bash,就不是很好搞... 一個解法是用 /usr/bin/env bashPATH 找,但也不是完全保險的方法 (PATH 有時候會清空...)。

在 Shell 下一行用 SQLite 查詢 CSV 內的資料

Simon Willison 這邊看到 command line 下用 SQLite 的技巧:「One-liner for running queries against CSV files with SQLite」。

範例指令是這樣 (整理了一下排版):

sqlite3 :memory: \
    -cmd '.import -csv taxi.csv taxi' \
    'SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi GROUP BY passenger_count'

可以看出來這個方式是將 csv 檔先讀到 in-memory database (:memory:),再用 SQLite 下指令處理,另外也可以自己變化,應該可以透過 /dev/stdin 這樣的方式讀 pipe 的東西。

拿來簡單跑一些東西應該還不賴?

moreutils

今天的 Hacker News Daily 上面看到「Moreutils: A collection of Unix tools that nobody thought to write long ago (joeyh.name)」這則,講 moreutils 這套工具。

翻了一下之前在「當程式沒問題時就會吃掉輸出的 chronic」這邊有提過 chronic 了,原文的討論裡面也提到了其他工具的用法,像是 sponge 可以在 pipe stdin 都收完後才開檔案寫入,可以避免 shell 直接先把檔案幹掉的問題:

awk '{do_stuff()}' myfile.txt | sort -u | column --table > myfile.txt

在這個例子裡面因為 myfile.txt 先被 shell 清空幹掉了,awk 就讀不到東西,這時候可以用 sponge 接,等到 pipe stdin 都收完後才寫檔案:

awk '{do_stuff()}' myfile.txt | sort -u | column --table | sponge myfile.txt

另外是 vipe,可以在先將程式輸出的結果丟進 $EDITOR 裡面,然後再往後丟,像是:

git branch | vipe | xargs git branch -D

還有其他的工具可以用,我自己是把 moreutils 當標配在裝了...

與 jq 互相配合的 jc

Simon Willison 的 blog 上看到的工具:「jc」,專案的網站:「JSON CLI output utility」。

可以把許多種輸出結果轉成 JSON 格式:

CLI tool and python library that converts the output of popular command-line tools and file-types to JSON or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.

所以就可以這樣用:

dig example.com | jc --dig

然後再丟給 jq

dig example.com | jc --dig | jq -r '.[].answer[].data'

支援的格式不少,在「Parsers」這段可以看到。

Ubuntu 22.04 後可以直接透過系統的 apt 安裝:「Ubuntu – Details of package jc in jammy」,在那之前也可以透過 pip 裝起來用...

等 Ubuntu 22.04 出了以後應該會變成標配安裝...

FreeBSD 把 root 預設的 shell 改成 /bin/sh

Hacker News 首頁上看到 FreeBSD 把 root 的 shell 從 /bin/csh 換成 /bin/sh 了:「sh(1): make it the default shell for the root user」,Hacker News 上的討論也可以看一看:「FreeBSD switches the default root shell from csh to sh (freebsd.org)」。

依照說明是把 FreeBSD 的 /bin/sh 加上了不少東西,所以算是堪用了:

In the recent history sh(1) has gain the missing features for it to
become a usable interractive shell:
- command completion
- persistent history support
- improvements on the default bindings in emacs mode
- improvements in the vi mode (repect $EDITOR)
- print a newline when exiting via ^D
- default prompt and improvements on how PS1 can be configured
- and more.

This changes also simplifies making tiny freebsd images with only sh(1)
as a shell

以前也是用 csh 系列的 (像是 tcsh),後來開始用 Linux 就往 BashZsh 定居了...

很久沒出新版的 mosh...

在今天的 Hacker News Daily 上看到 mosh 的連結,看了一下 Hacker News 上的討論,發現原作者有上去跟大家討論一些目前的情況:「Mosh: The Mobile Shell (mosh.org)」。

原作者是 Keith Winstein,在 Hacker News 上的帳號名稱是 keithwinstein,可以用 Ctrl-F 翻一下他回應的東西。

關於四年沒有新版的原因,一方面是他覺得已經將後續的開發與維護交棒出去,不應該因為接手的人太忙就冒出來;另外一方面是目前的版本也沒有安全問題,沒有迫切需要丟出一個新版本:

I think the truth is that we don't feel like we need a release. We've never had a security hole, our track record speaks for itself, and I wouldn't really want us to rush anything and blow that. There are some features that it would be really nice to have in a release (like 24-bit color support, and working around a recent MacOS clock bug), but I handed over the maintainership to somebody else about six years ago and that person is currently, I think, dealing with a bunch of stuff (look around the world the last year...). I'm not eager to step back in and bigfoot them -- especially when I'm no longer particularly familiar with the codebase (and recent commits) as I used to be.

Mosh works as advertised and has never had a security hole -- we're pretty proud of that! We'll probably cut a release at some point to add those features (24-bit colors, the MacOS clock workaround) but I'm not feeling like it's urgent enough to upset what I had hoped was a transition plan.

It would feel arrogant to compare Mosh to TeX, but it doesn't seem that crazy to imagine that some software might reach a point where it has accomplished 95% of its goals, and the benefit from adding further features has to be weighed against the risk of introducing a security hole or other regression through further churn. If the TCP specification, or OpenSSH, or TeX, or GNU bash had canonical GitHub repositories, they would probably be full of a bunch of user support issues and inactive PRs too. :-)

看了一下 GitHubContributors 這頁,可能是 cgull

的確是一個很穩定的軟體,在桌機與筆電上面都用了八九年了,解決了網路切換 (或是不穩定) 的問題:「把 SSH 換成 Mosh」。

Mac OS 7/8/9 上的 SSH client

Hacker News 首頁上看到「Ssheven: A modern SSH client for Mac OS 7-9 (github.com/cy384)」這個,為了 Mac OS 7/8/9 (PowerPC 平台) 實做 SSH client。

翻了一下程式碼,看起來是透過 libssh2 實做加解密的部份,依照 libssh2 的官網,支援的演算法雖然不是超級新,但看起來還算可以 (至少有目前還算安全的演算法可以用):

Hacker News 上有看到一些老機器跑出來玩 XD

tikwidd 8 hours ago

So far it's working well on my LC III (68030 with 36mb ram)!
I'm writing this comment from the LC III using w3m over ssh :)