$ echo 'URL="https://go.dev/dl/go1.23.2.linux-amd64.tar.gz" CHECKSUM="542d3c1705f1c6a1c5a80d5dc62e2e45171af291e755d591c5e6531ef63b454e" ; TMP="$(mktemp -d)" && [ "$(curl -fsSL "$URL" | tee "$TMP/go.tar.gz" | sha256sum | cut -d\ -f1)" = "$CHECKSUM" ] && rm -rf /usr/bin/go.toolchain /usr/bin/go && tar -C "$TMP" -xzf "$TMP/go.tar.gz" && mv "$TMP/go" /usr/bin/go.toolchain && ln -sf /usr/bin/go.toolchain/bin/go /usr/bin/go' | doas sh
H:=3; Graphics3D[Join[Table[Table[Sphere[{x+1/2*j, y+1/2*j, 1/Sqrt[2]*j}, 1/2], {x, H-j}, {y, H-j}], {j, 0, H-1}]]]
I just let a system auto-upgrade from Fedora 38 to Fedora 40 and it kernel-panicked.
$ ls -d ~/git/* | xargs -I{} git -C {} fetch
Traces looked suspiciously flat; I had set it to one hours ago ...
I haven't yet tested it, yet "GODEBUG=sbrk" seems to have been potentially useful the last three days. Cf. https://pkg.go.dev/runtime [2024-09-06]
$ sh <<'EOF' #! /bin/sh # # Jonathan Frech, 2024-08-30 cd "$(mktemp -d)" export GOEXPERIMENT=aliastypeparams go version go mod init a mkdir b cat >b/b.go <<'EOGO' package b type T[V any] = S[V] type S[V any] struct { X V } EOGO cat >a.go <<'EOGO' package a import "a/b" type T b.T[int] func main() { } EOGO go build EOF go version go1.23.0 linux/amd64 go: creating new go.mod: module a # a <unknown line number>: internal compiler error: panic: importing generic type aliases is not supported in Go 1.23 (see issue #68526) Please file a bug report including a short program that triggers the error. https://go.dev/issue/new
Cf. https://web.archive.org/web/20240830162518/https://github.com/golang/go/issues/68526#issuecomment-2251551529 [2024-08-30]
$ cat local-mean-time-time-zone.go package main import ( "fmt" "time" ) func main() { t := time.Date(1970, time.January, 1, 1, 0, 0, 0, time.Local) fmt.Printf("t=%s\n", t.GoString()) zone1, offset1 := t.Zone() fmt.Printf("zone1=%q, offset1=%d\n", zone1, offset1) zone2, offset2 := time.Time{}.In(t.Location()).Zone() fmt.Printf("zone2=%q, offset2=%d\n", zone2, offset2) zone3, offset3 := time.Time{}.In(time.FixedZone(zone1, offset1)).Zone() fmt.Printf("zone3=%q, offset3=%d\n", zone3, offset3) } $ go run local-mean-time-time-zone.go t=time.Date(1970, time.January, 1, 1, 0, 0, 0, time.Local) zone1="CET", offset1=3600 zone2="LMT", offset2=3208 zone3="CET", offset3=3600
$ go env GOSUMDB off $ su -l j -c 'cd "$(mktemp -d)" && go mod init toolchain_update && go get go@1.23' Password: go: creating new go.mod: module toolchain_update go: updating go.mod requires go >= 1.23.0; switching to go1.23.0 go: downloading go1.23.0 (linux/amd64) go: upgraded go 1.22.3 => 1.23.0 $ go version go version go1.22.3 linux/amd64 $ ~/go/pkg/mod/golang.org/toolchain\@v0.0.1-go1.23.0.linux-amd64/bin/go version go version go1.23.0 linux/amd64 $ doas ln -sf ~/go/pkg/mod/golang.org/toolchain\@v0.0.1-go1.23.0.linux-amd64/bin/go /usr/bin/go doas (j@jfrech) password: $ go version go version go1.23.0 linux/amd64
[1] gives multiple reasons for version >2, yet [2] only talks about the checksum algorithm.
[1] https://git.kernel.org/pub/scm/git/git.git/tree/bundle.c?id=159f2d50e75c17382c9f4eb7cbda671a6fa612d1#n526 [2024-08-28] [2] https://git.kernel.org/pub/scm/git/git.git/tree/bundle.c?id=159f2d50e75c17382c9f4eb7cbda671a6fa612d1#n553 [2024-08-28]
$ git version git version 2.39.2 $ git log commit b83711a25156e592478a33b6f01b9ad6c1a3bd2d (HEAD -> master, origin/master, origin/HEAD) Author: <> Date: Thu Jan 1 00:00:00 1970 +0000 master $ git cat-file -p b83711a25156e592478a33b6f01b9ad6c1a3bd2d tree f2430429abb1bc13321010e6ca10369691ba7776 author <> -62135596800 +0000 committer <> -62135596800 +0000 $ git fsck error in commit b83711a25156e592478a33b6f01b9ad6c1a3bd2d: badDateOverflow: invalid author/committer line - date causes integer overflow Checking object directories: 100% (256/256), done.
$ printf '\x78\xda' | hd 00000000 78 da |x.| 00000002
$ go mod tidy go: warning: "all" matched no packages
Just now, Vim lied in its rendering. A text editor which displays something else than is in the buffer. I need to write Wimzig and turn my back against Vim!
echo eW91IGNhbiB0cnVzdNesID8gbm8gb25lCg== | base64 -d | vim - f?
May be caused by the "pkg" import being shadowed by a local variable.
$ find * -type f | grep '\.go$' | xargs -I{} sed --in-place 's!pkg.jfrech.com/...!pkg.jfrech.com/...!g'
$ go doc os/.SEEK_CUR package os // import "os" const ( SEEK_SET int = 0 // seek relative to the origin of the file SEEK_CUR int = 1 // seek relative to the current offset SEEK_END int = 2 // seek relative to the end ) Seek whence values. Deprecated: Use io.SeekStart, io.SeekCurrent, and io.SeekEnd.
$ go install golang.org/x/pkgsite/cmd/pkgsite@latest && pkgsite -http=:8081 -open
$ cd ~/git/go-git && go doc | grep -i sys | sed 's/\$//' | sh
Effectively functions as blocking websites which heavily rely on dynamicity (e.g. DOM hydration).
Settings > Privacy and security > Security > Site and Shields Settings > JavaScript > Not allowed to use JavaScript > Add
$ cd ~/git/go-git && \ > go test ./... -coverpkg=./encoding/binary/,./encoding/binary/internal \ > -coverprofile=/tmp/cover.out && go tool cover -html=/tmp/cover.out
Cf. https://stackoverflow.com/a/33457070 [2024-08-07]
"go test -coverpkg=all" Cf. https://go.dev/doc/go1.10#test [2024-08-07]
$ su -
$ while true; do find . -type f | grep '_test\.go$' | while IFS= read -r testdotgo; do grep '^func Fuzz[A-Za-z0-9_]\+(f \*testing.F) {$' "$testdotgo" | grep -o 'Fuzz[^(]*' | while IFS= read -r fuzztarget; do echo "package=$(dirname "$testdotgo") fuzztarget=$fuzztarget"; done; done | sort -R | head -n1 | sed 's!$!; echo "package=$package"; echo "fuzztarget=$fuzztarget"; go test "$package" -fuzz="$fuzztarget" -parallel=6 -fuzztime=10m!' | sh; done
$ git version git version 2.39.2 $ git push --force-with-lease Everything up-to-date $ git push --force-with-leas Everything up-to-date $ git push --force-with-lea Everything up-to-date $ git push --force-with-le Everything up-to-date $ git push --force-with-l Everything up-to-date $ git push --force-with- Everything up-to-date $ git push --force-with Everything up-to-date $ git push --force-wit Everything up-to-date $ git push --force-wi Everything up-to-date $ git push --force-w Everything up-to-date $ git push --force-w Everything up-to-date $ git push --force- error: ambiguous option: force- (could be --force-with-lease or --force-if-includes) ...
I had seen ($)
before in passing and always found it intriguingly beautiful. On a walk today, I realized how it enables one to utilize infinite lists of non-tabular types:
ghci> import Control.Monad (join) ghci> join . zipWith ($) (cycle [("%" ++), id]) . fmap pure $ "abcdef0123456789" "%ab%cd%ef%01%23%45%67%89"
Since fmap pure
is not the prettiest, one can rewrite to join . zipWith ($) (cycle [\c -> ['%',c], pure])
.
./SRC.go:L:C: implicit function instantiation requires go1.18 or later (-lang was set to go1.17; check go.mod)
$ while true; do export FUZZ_TARGET="$(grep '^func Fuzz[A-Za-z0-9_]\+(f \*testing.F) {$' *_test.go | grep -o 'Fuzz[^(]*' | sort -R | head -n1)"; echo "$FUZZ_TARGET=$FUZZ_TARGET"; go test . -fuzz="$FUZZ_TARGET" -parallel=6 -fuzztime=10m || break; done
$ hd /dev/urandom | sed 's/^[^ ]*//; s/^ *//; s/|.*//; s/ / /g; s/ *$//; s/^/ /; s/ /\\x/g' | head \x14\x6c\x3f\x4e\x28\x03\xfe\x16\x1d\x57\x71\x8c\xb1\x17\x6e\x74 \x68\x6c\xe1\xb3\xc8\x74\xe6\xdc\x26\x28\x5d\x57\xc3\x91\x4e\x09 \x71\xb2\x6d\x3f\xf5\x4f\xb4\xbc\x77\x01\xb7\xf3\x43\x65\x98\x1a \xce\xd2\x48\xf2\x33\x89\x4d\x57\x75\x0c\x04\x32\x12\x2d\x52\xd4 \x89\x8a\x05\x14\xb9\x6a\x4d\xda\x62\xa5\x19\x93\xa4\x3e\x18\x5c \xe7\x8f\x02\xd4\x9e\x3f\x92\x52\x40\x36\xc0\x99\xe0\xd1\x2f\x30 \xa5\x0a\x90\xf4\x31\xac\xa6\xc4\x6e\x61\xd7\x63\xaf\xdc\x72\x21 \xa6\x9b\x85\x36\x23\xda\x72\x80\x4d\xca\x98\xcb\x8b\xa8\xb7\x94 \x16\x96\xe9\x7e\x30\x20\xc4\xf3\xf0\x15\x02\xa5\x09\xa9\xcb\x64 \x5f\x59\x37\x84\x5c\x59\x59\x3e\xcd\x37\x32\x1e\x56\x20\xce\x00
systemctl cat "$UNIT" | sed 's/^# //;q'
Just using Google's DN server ("8.8.8.8") ... Who has deleted my resolver configuration? I have removed "testing" from "/etc/apt.sources".
# rm -f /etc/resolv.conf && echo nameserver 8.8.8.8 >/etc/resolv.conf && apt install --reinstall resolvconf network-manager libnss-resolve Reading package lists... Done Building dependency tree... Done Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: libnl-route-3-200 : Depends: libnl-3-200 (= 3.4.0-1+b1) but 3.7.0-0.3 is to be installed libnss-resolve : Depends: systemd (= 247.3-7+deb11u5) but 255.4-1 is to be installed E: Unable to correct problems, you have held broken packages.
# systemctl restart resolved Failed to restart resolved.service: Unit resolved.service not found. # dpkg-reconfigure resolvconf dpkg-query: package 'resolvconf' is not installed and no information is available Use dpkg --info (= dpkg-deb --info) to examine archive files. /usr/sbin/dpkg-reconfigure: resolvconf is not installed
# apt install resolvconf Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: resolvconf 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded. Need to get 72.7 kB of archives. After this operation, 204 kB of additional disk space will be used. Ign:1 http://deb.debian.org/debian bullseye/main amd64 resolvconf all 1.87 Ign:1 http://deb.debian.org/debian bullseye/main amd64 resolvconf all 1.87 Ign:1 http://deb.debian.org/debian bullseye/main amd64 resolvconf all 1.87 Err:1 http://deb.debian.org/debian bullseye/main amd64 resolvconf all 1.87 Temporary failure resolving 'deb.debian.org' E: Failed to fetch http://deb.debian.org/debian/pool/main/r/resolvconf/resolvconf_1.87_all.deb Temporary failure resolving 'deb.debian.org' E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
Why is # swapon /swapfile
not reboot-persistent?
# [ "$(id -u)" -eq 0 ] && [ ! -e /swapfile ] && fallocate -l 32G /swapfile && chmod 0600 /swapfile && /usr/sbin/mkswap /swapfile && /usr/sbin/swapon /swapfile && /usr/sbin/swapon --show
$ hd /dev/urandom | vim
You get thrown into the second vtty screen, yet cannot interact with the editor. Screen resizing makes "hd"'s output visible.
$ cd ~ && go test "$(echo -e '\x01')" panic: path "\x01" not in error "invalid import path \"\\x01\"" [recovered] panic: path "\x01" not in error "invalid import path \"\\x01\"" goroutine 1 [running]: cmd/go/internal/load.(*preload).flush(0xc000030950) cmd/go/internal/load/pkg.go:1132 +0x74 panic({0x9cef40?, 0xc000030a00?}) runtime/panic.go:770 +0x132 cmd/go/internal/load.ImportErrorf({0x7ffc35246ace, 0x1}, {0xa9d423?, 0x1?}, {0xc0001a1240?, 0xc0001a15b8?, 0x0?}) cmd/go/internal/load/pkg.go:542 +0x174 cmd/go/internal/load.(*Package).load(0xc00019a608, {0xba6e70, 0xf8d0c0}, {0x0, 0x1, 0x0, 0x0, 0x0, 0x0}, {0x7ffc35246ace, ...}, ...) cmd/go/internal/load/pkg.go:1949 +0x1214 cmd/go/internal/load.loadImport({0xba6e70, 0xf8d0c0}, {0x0, 0x1, 0x0, 0x0, 0x0, 0x0}, 0xc000030950, {0x7ffc35246ace, ...}, ...) cmd/go/internal/load/pkg.go:794 +0x546 cmd/go/internal/load.PackagesAndErrors({0xba6e70?, 0xf8d0c0?}, {0x0, 0x1, 0x0, 0x0, 0x0, 0x0}, {0xc0000307e0, 0x1, ...}) cmd/go/internal/load/pkg.go:2882 +0xa2b cmd/go/internal/test.runTest({0xba6e70, 0xf8d0c0}, 0xf1f4e0, {0xc0000222f0?, 0x9cef40?, 0x4c?}) cmd/go/internal/test/test.go:701 +0x37b main.invoke(0xf1f4e0, {0xc0000222e0, 0x2, 0x2}) cmd/go/main.go:257 +0x5c4 main.main() cmd/go/main.go:175 +0x6d5
Cf. https://cs.opensource.google/go/go/+/refs/tags/go1.22.5:src/cmd/go/internal/load/pkg.go;l=539 [2024-07-14]
I classify this behaviour a bug.
[EDIT 2024-08-06] Cf. https://github.com/golang/go/issues/68737 [2024-08-06]
$ doas sh -c 'apt update && apt upgrade --assume-yes && apt autoremove --assume-yes' ... $ yt-dlp --version 2023.03.04 $ [ "$(curl -fsSL https://github.com/yt-dlp/yt-dlp/releases/download/2024.07.09/SHA2-256SUMS | grep '\<yt-dlp_linux$' | grep -o '^[0-9a-f]*')" = 77c1571df6c29371e01c26c171ecd92d85aca7b8ae830841bb05adce68778798 ] && mkdir -p ~/.local/bin/ && [ "$(curl -fsSL https://github.com/yt-dlp/yt-dlp/releases/download/2024.07.09/yt-dlp_linux | tee /tmp/yt-dlp | sha256sum | grep -o '^[0-9a-f]*')" = 77c1571df6c29371e01c26c171ecd92d85aca7b8ae830841bb05adce68778798 ] && chmod +x /tmp/yt-dlp && mv /tmp/yt-dlp ~/.local/bin/ $ yt-dlp --version 2024.07.09
$ cd ~/git/go-git/ && grep -rI '\.Checksummer()' | grep -o '^[^:]*' | xargs -I{} sed --in-place 's/\.Checksummer()/.NewChecksummer()/' {}
$ du -hs * | sort -h ... $ du -hs * | sort -h | tail -n 3 | xargs rm -rf
Since using Go's embed.FS and my weblog being well over a few gigabytes, Systemd's OOM killer has in the past already sometimes shot down my webserver. Today it happened: my webserver couldn't get afoot even a second. I realized my VPS hadn't had any swap provisioned, so I quickly raced to get it back online:
webserver # swapon --show webserver # fallocate -l 4G /swapfile webserver # chmod 600 /swapfile webserver # mkswap /swapfile mkswap: /swapfile: warning: wiping old swap signature. Setting up swapspace version 1, size = 8 GiB (8589930496 bytes) no label, UUID=7f345750-6365-45c3-b5bd-e4f47e91ba8a webserver # swapon /swapfile webserver # swapon --show NAME TYPE SIZE USED PRIO /swapfile file 8G 524K -2
$ git push origin --delete devel/jfrech
After a long sleep, WiFi dropped:
$ doas service netif restart
To e.g. mount via $ zpool import -a
$ mount -o rw /
Cf. https://forums.freebsd.org/threads/solved-mount-o-rw-doesnt-work.48081/ [2024-06-23]
(For ZFS Live CD systems, use zfs set readonly=off zroot
and on non-FreeBSD systems mount -o remount,rw /
may be useful.)
cd ~/git/ && find . -maxdepth 1 -mindepth 1 -type d | LC_ALL=C sort | while read repo; do echo "### $repo"; git -C "$repo" status; echo; done
When refactoring, I am often unsure if I have kept the semantics intact. Thus, a tool which fuzzes different versions of pure functions à la $ go test -run=./pkg/tobe/scrutinized/RefactoredFunc -noreg=7e2f7aef92cd858
, where 7e2f7aef92cd858 is the old revision, could be a massive boon. Successful fuzzing wouldn't prove but indicate no regression took place.
ICE (cf. https://blog.jfrech.com/287/ [2024-05-27]) was already fixed, but I was on a lagging point release.
$ echo 'URL="https://go.dev/dl/go1.22.3.linux-amd64.tar.gz" CHECKSUM="8920ea521bad8f6b7bc377b4824982e011c19af27df88a815e3586ea895f1b36" ; [ "$(curl -f#SL "$URL" | tee /tmp/go.tar.gz | sha256sum | cut -d\ -f1)" = "$CHECKSUM" ] && rm -rf /usr/local/go && tar -C /usr/local -vxzf /tmp/go.tar.gz' | doas sh
Cf. https://blog.jfrech.com/235/ [2024-05-27]
$ go version go version go1.22.1 linux/amd64 $ cat /tmp/internal-compiler-error.go package main func main() { panic("?") closure := func() {} outer: for range 0 { goto outer } closure() } $ go run /tmp/internal-compiler-error.go # command-line-arguments CLOSURE [/tmp/internal-compiler-error.go:11:5:var closure func()] <unknown line number>: internal compiler error: assertion failed Please file a bug report including a short program that triggers the error. https://go.dev/issue/new
$ sed 's/passed in slices/passed-in slices/g' --in-place https://cs.opensource.google/go/go/+/refs/tags/go1.22.3:src/slices/slices.go;l=341
$ openssl s_client -connect pop3.tal.de:995 -debug
$ cd ~/git/brief/ && godoc -http=:8082 & brave-browser --incognito 'http://localhost:8082/pkg/pkg.jfrech.com/brief/?m=all'
Cf. https://stackoverflow.com/a/67189854 [2024-05-20]
I detest with a passion the pretentiousness of other people creating software which but evokes vertiginous disgust.
$ vim /tmp/.go :vspli iI won't be highlighted in the right split.ESCO/*
$ vim --version VIM - Vi IMproved 9.0 (2022 Jun 28, compiled May 04 2023 10:24:44) Included patches: 1-1378, 1499 Modified by team+vim@tracker.debian.org Compiled by team+vim@tracker.debian.org Huge version without GUI. Features included (+) or not (-): +acl +file_in_path +mouse_urxvt -tag_any_white +arabic +find_in_path +mouse_xterm -tcl +autocmd +float +multi_byte +termguicolors +autochdir +folding +multi_lang +terminal -autoservername -footer -mzscheme +terminfo -balloon_eval +fork() +netbeans_intg +termresponse +balloon_eval_term +gettext +num64 +textobjects -browse -hangul_input +packages +textprop ++builtin_terms +iconv +path_extra +timers +byte_offset +insert_expand -perl +title +channel +ipv6 +persistent_undo -toolbar +cindent +job +popupwin +user_commands -clientserver +jumplist +postscript +vartabs -clipboard +keymap +printer +vertsplit +cmdline_compl +lambda +profile +vim9script +cmdline_hist +langmap -python +viminfo +cmdline_info +libcall -python3 +virtualedit +comments +linebreak +quickfix +visual +conceal +lispindent +reltime +visualextra +cryptv +listcmds +rightleft +vreplace +cscope +localmap -ruby +wildignore +cursorbind -lua +scrollbind +wildmenu +cursorshape +menu +signs +windows +dialog_con +mksession +smartindent +writebackup +diff +modify_fname +sodium -X11 +digraphs +mouse -sound -xfontset -dnd -mouseshape +spell -xim -ebcdic +mouse_dec +startuptime -xpm +emacs_tags +mouse_gpm +statusline -xsmp +eval -mouse_jsbterm -sun_workshop -xterm_clipboard +ex_extra +mouse_netterm +syntax -xterm_save +extra_search +mouse_sgr +tag_binary -farsi -mouse_sysmouse -tag_old_static system vimrc file: "/etc/vim/vimrc" user vimrc file: "$HOME/.vimrc" 2nd user vimrc file: "~/.vim/vimrc" user exrc file: "$HOME/.exrc" defaults file: "$VIMRUNTIME/defaults.vim" fall-back for $VIM: "/usr/share/vim" Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -Wdate-time -g -O2 -ffile-prefix-map=/build/vim-JA6Vy9/vim-9.0.1378=. -fstack-protector-strong -Wformat -Werror=format-security -DSYS_VIMRC_FILE=\"/etc/vim/vimrc\" -DSYS_GVIMRC_FILE=\"/etc/vim/gvimrc\" -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 Linking: gcc -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -o vim -lm -ltinfo -lselinux -lsodium -lacl -lattr -lgpm
https://go.dev/doc/comment
https://go.dev/ref/spec
When considering tabs versus four spaces, one argument for the former (besides gofmt-compliance) is reduced bytes in source files (I don't want to overwhelm alien historians in 3000 years with unnecessarily generated entropy). One question then is if after compression (i.e. Git database or transparent disk encryption), the same byte reduction is still guaranteed.
I have a hunch that no non-trivial compression algorithm (the identity encoding or bloating encodings surely satisfy the following) has the property that removing bytes before compression results in a byte reduction in the compressed representation. Or such an algorithm would need to give up usability for non-hyper-repetetive data.
"Parsable" yet "salvageable".
fuzzmodule () { cd "$(mktemp -d)" && pwd && git clone -q "$1" ./repo/ && cd repo && find . | grep '_test.go' | while IFS= read -r testdotgo; do grep '^func Fuzz' "$testdotgo" | grep -o 'Fuzz[a-zA-Z0-9_]*' | while IFS= read -r fuzztarget; do echo "$(dirname "$testdotgo")" "$fuzztarget"; done; done | sort -R | sed q | while IFS=' ' read -r dir fuzz; do cd "$dir" && pwd && echo "$fuzz" && go test -fuzz='^'"$fuzz"'$' -fuzztime=10s -parallel=6 || return 1; done; }; while true; do fuzzmodule 'https://git.jfrech.com/~jfrech/brief.git' || break; done
$ go version && go build go version go1.20.3 linux/amd64 go: errors parsing go.mod: ***/go.mod:3: invalid go version '1.22.1': must match format 1.23
As of Go 1.22, time.ParseDuration's documentation doesn't mention that two different "mu" Unicode code points are recognized.
Cf. https://cs.opensource.google/go/go/+/refs/tags/go1.22.2:src/time/format.go;l=1576-1589 [2024-04-28]
$ drop () { awk "{if(NR>$1)print}" "${@:2}"; }
Cf. https://hackage.haskell.org/package/base-4.19.1.0/docs/Prelude.html#v:drop [2024-04-28]
$ SOURCE=source.pdf && { tmp="$(mktemp)" && n="$(qpdf --show-npages "$SOURCE")" && qpdf "$SOURCE" --pages . "$n-$n" -- "$tmp" && echo "$tmp" ;}
$ go test ./exactly/one/package -coverprofile=/tmp/cover.out -cpuprofile=/tmp/cpu.out $ go tool cover -html=/tmp/cover.out $ go tool pprof -http=:8081 /tmp/cpu.out $ go test ./... -coverprofile=/tmp/cover.out $ go tool cover -html=/tmp/cover.out
What is going on is that directory entries are sorted according to their name plus a trailing slash.
Cf. https://git.kernel.org/pub/scm/git/git.git/tree/tree.c?id=21306a098c3f174ad4c2a5cddb9069ee27a548b0#n99 [2024-04-17]
$ cd ~/mirrored.git/git/ && doas apt install --assume-yes libssl-dev libcurl4-openssl-dev
When developing pkg.jfrech.com/go/git/edit, a test case based off of ~jfrech/brief.git didn't roundtrip. The reason was a non-canonical tree; I am fairly certain generated by standard Git (which version I unfortunately do not know). Note how "constants.go" is listed before "constants":
$ cd ~/git/brief/ && git cat-file -p 2cd4f18048d7796e6a052fb53c23611511d72d0a 040000 tree 44afdd97596ea8cec785ab0dbc71b8b9d18337f7 blobs 100644 blob f9b52c499bab4e7fe63725666be94c25b33b9e0e briefroot.go 040000 tree c845b744ee6678022b8ad37a96ad9d2dcd56cf1f cli 040000 tree 0c528cdf5b38096abb27d353d8a9f89f866dba8e client 040000 tree 6f14e3c7cae15d428ab11f2ccc3a076177c20d13 cmd 040000 tree 17cc7b083aace860178b934e7ed56d6bb74dc36a columnwriter 040000 tree 1d7078031f42e530c5adcdc690a36a586f72d986 config 100644 blob 80cc6978e2f56c744d5ba49be8317e1e05c9db9d constants.go 040000 tree 4a933b059b09892763c75aac782290458f47d7a2 constants 040000 tree 33725ec54ba5604f10ef64f62aecf8814e44f4f3 decode 040000 tree 20a33dae0bd8e4d21fab71b93c4ba790525c4656 escape 100644 blob a56580fa1b8d1f9e406d2b60b4c3160913b3b871 go.mod 100644 blob 7020244b67af393a55ba22c5d3f91f22c136366e go.sum 100644 blob 293d3a958e41ea63ee22a7d3f55863c3bb9da732 licence.txt 040000 tree 38a470d2eecaa17b0b61c65f0ef2f28551aa8d0b linenormalisation 040000 tree 487a34aa8af26e70cab514e18d83a87e77c054f5 mailx 040000 tree a6a88772a08f4c833b73709099d839fc9ebbc4b4 markdownish 040000 tree e09fa29e0ac3b07be370b0bb1009d0fc157854f4 message 040000 tree 528dffaececcbe50ba55d7b67d53eb36480e93ee network 040000 tree 7da19041bf5172cdb4fed353a5a74953d05ab37d stdlibx 040000 tree 7eafc184ca8f0c4ba3d3f0fb3439f42d57a0b530 tequat 040000 tree b78f826846edab4e0db9a90e5f0af38341994260 util 040000 tree 455d02f22a81f616bd79caaa1d1119b025244304 validate
More surprisingly, this appears to be standard Git behaviour:
$ cd "$(mktemp -d)" && git version && git init && export GIT_AUTHOR_NAME=gan GIT_AUTHOR_EMAIL=gae GIT_AUTHOR_DATE='2024-04-17T00:18+0200' GIT_COMMITTER_NAME=gcn GIT_COMMITTER_EMAIL=gce GIT_COMMITTER_DATE='2024-04-17T00:18+0200' && mkdir a && touch a/b && git add . && git commit -m 1 && touch a.c && git add . && git commit -m 2 && git cat-file -p HEAD | grep tree && git cat-file -p HEAD^ | grep tree && echo && git cat-file -p 1222ef52a69967362e391785e5b2e57d3a43a55c && echo && git cat-file -p 878e27c626266ac04087a203e4bdd396dcf74763 git version 2.39.2 Initialized empty Git repository in /tmp/tmp.13oggYBQaq/.git/ [master (root-commit) a6cc959] 1 Author: gan1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a/b [master 8acae20] 2 Author: gan 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a.c tree 1222ef52a69967362e391785e5b2e57d3a43a55c tree 878e27c626266ac04087a203e4bdd396dcf74763 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a.c 040000 tree 4277b6e69d25e5efa77c455340557b384a4c018a a 040000 tree 4277b6e69d25e5efa77c455340557b384a4c018a a
For only files, the behaviour is nothing out of the ordinary:
$ cd "$(mktemp -d)" && git version && git init && GIT_AUTHOR_NAME=gan GIT_AUTHOR_EMAIL=gae GIT_AUTHOR_DATE='2024-04-17T00:18+0200' GIT_COMMITTER_NAME=gcn GIT_COMMITTER_EMAIL=gce GIT_COMMITTER_DATE='2024-04-17T00:18+0200' && touch a aa && git add . && git commit -m c && git cat-file -p "$(git cat-file -p HEAD | grep tree | sed s:tree.::)" git version 2.39.2 Initialized empty Git repository in /tmp/tmp.ae7zS7zHql/.git/ [master (root-commit) 7255e1b] c Author: gan2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a create mode 100644 aa 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 aa
What is going on???
master $ cd "$(mktemp -d)" && git version && git init && GIT_AUTHOR_NAME=gan GIT_AUTHOR_EMAIL=gae GIT_AUTHOR_DATE='2024-04-17T00:18+0200' GIT_COMMITTER_NAME=gcn GIT_COMMITTER_EMAIL=gce GIT_COMMITTER_DATE='2024-04-17T00:18+0200' && mkdir a && touch a/a a. && git add . && git commit -m c && git cat-file -p "$(git cat-file -p HEAD | grep tree | sed s:tree.::)" git version 2.39.2 Initialized empty Git repository in /tmp/tmp.hT42Xt2IRr/.git/ [master (root-commit) e648bce] c Author: gan2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a. create mode 100644 a/a 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a. 040000 tree 496d6428b9cf92981dc9495211e6e1120fb6f2ba a master $ cd "$(mktemp -d)" && git version && git init && GIT_AUTHOR_NAME=gan GIT_AUTHOR_EMAIL=gae GIT_AUTHOR_DATE='2024-04-17T00:18+0200' GIT_COMMITTER_NAME=gcn GIT_COMMITTER_EMAIL=gce GIT_COMMITTER_DATE='2024-04-17T00:18+0200' && touch a a. && git add . && git commit -m c && git cat-file -p "$(git cat-file -p HEAD | grep tree | sed s:tree.::)" git version 2.39.2 Initialized empty Git repository in /tmp/tmp.tdyM6oqJ4U/.git/ [master (root-commit) 440f1e8] c Author: gan 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a create mode 100644 a. 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a.
https://pkg.go.dev/builtin@go1.22.2#string says "A string may be empty, but not nil.". The same sentence applies to a slice of bytes, though with a different meaning.
% doas sh -c 'set -e; [ "$(id -u)" -eq 0 ] || { echo "insufficient privileges"; exit 1; }; [ ! -d /usr/local/go ] || { echo "go already installed"; exit 1; }; rm -f /tmp/go.tar.gz && checksum="$(curl -fsSL https://go.dev/dl/go1.22.2.linux-amd64.tar.gz | tee /tmp/go.tar.gz | sha256sum | grep -o "^[0-9a-f]\{64\}")"; [ "$checksum" = 5901c52b7a78002aeff14a21f93e0f064f74ce1360fce51c6ee68cd471216a17 ] || { echo "bad checksum"; exit 1; }; cd /usr/local && tar xf /tmp/go.tar.gz; [ -e /usr/bin/go ] || { cd /usr/bin && ln -sf /usr/local/go/bin/go; }; go version'
I today learnt that type T S
and type T = S
are two different things.
Cf. https://go.dev/ref/spec#Alias_declarations [2024-04-09]
I recently started using
func (t *T) M() { _ = *t // ... }
to assert the method is called on a non-nil type. Maybe I should instead be using the much more mysterious
func (t *T) M() { t = &*t // ... }
. Note that "&*" can be repeated arbitrarily often.
Thinking of closing a channel as sending a sentinel value is an approximate thought model: the sentinel value has access to a hidden one-sized extra buffer.
ch := make(chan struct{}) close(ch) // does not block ch = make(chan struct{}, 3) ch <- struct{}{} ch <- struct{}{} ch <- struct{}{} close(ch) // does not block
$ pactl set-sink-mute @DEFAULT_SINK@ false && pactl set-sink-volume @DEFAULT_SINK@ 30%
filepath.Join(base, untrusted) // not sanitised filepath.Join(base, "/", untrusted) // not sanitised filepath.Join(base, filepath.Join("/", untrusted)) // sanitised filepath.Join(base, filepath.FromSlashes(path.Join("/", untrusted))) // sanitised, platform-cognisant
$ find ~/git/ -mindepth 1 -maxdepth 1 -type d | while IFS= read -r repo; do git -C "$repo" log; done | grep -A3 -B3 "$PATTERN"
I seem to always forget how one un-floats a window: Mod+MiddleMouseClick.
I today bound Mod+w to open my web browser. In testing key chord feel, I pressed Mod+i thinking it would be a no-op. However, in vanilla DWM, Mod+i increments and Mod+d decrements the number of windows put vertically ontop in the master area. The effect is, when Mod+i is pressed once and only two windows are opened, they look like they stacked vertically.
Cf. https://unix.stackexchange.com/a/65900 [accessed 2024-03-29]
$ go install golang.org/x/tools/cmd/godoc@latest && godoc -http=:8080
$ export GIT_SSH_COMMAND='ssh -o IdentitiesOnly=yes -i ~/.ssh/github'
$ git checkout --orphan $PREVIOUSLY_UNUSED_BRANCH_NAME
$ doas apt install --assume-yes lprng hplip ... $ lp -d "$(lpstat -p -d | grep '^printer' | cut -d\ -f2)" paper.pdf
I always want "a" and "b" pressed to use pixel-repeating scaling and no bottom cursor line. However, only the latter is supported by a flag: "$ sxiv -b a.png".
$ doas apt install --assume-yes pavucontrol $ pacmd list-sinks $ pavucontrol ... $ pactl info
$ ls "$HOME/git/" | while read repo; do echo "$repo"; git -C "$repo" status; echo; echo; done
$ git tag devel $ git push origin devel
$ cd "$(mktemp -d)" $ mkdir a $ ln -s a b $ rm b/ rm: cannot remove 'b/': Is a directory $ rm b
svw
-- smallest viewport height
Cf. https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units [accessed 2024-03-13]
# useradd -m -G mail -s /bin/bash $USERNAME # passwd $USERNAME ...
=== T H U N D E R B I R D === IMAP mail.domain.tld :993 SSL/TLS Autodetect SMTP mail.domain.tld :587 STARTTLS Normal passw.
As of Go 1.22, "bufio".(*Reader).WriteTo may emit w.(io.ReaderFrom).ReadFrom calls (cf. https://cs.opensource.google/go/go/+/refs/tags/go1.22.0:src/bufio/bufio.go;l=530) without mentioning it in its documentation.
Checking general domain availability: https://www.netcup.de/bestellen/domaincheck.php?domain=domain&tld=1
Checking mail availability: $ dig -t mx "$DOMAIN"
and possibly writing to info@DOMAIN
or postmaster@DOMAIN
.
Checking the WayBack Machine (https://web.archive.org/) for an old imprint.
$ ltrace a.out
$ echo "fingerprints" && ssh-keygen -lf ~/.ssh/known_hosts $ echo "public host keys" && ssh-keygen -H -F domain $ echo "rewrite known_hosts" && ssh-keygen -H
Fed up with Fedora 38's unbearable bugginess and disappointed by FreeBSD's Rust advances, I will now run Debian on my ThinkPad T470s.
$ curl -fsSL https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA256SUMS 64d727dd5785ae5fcfd3ae8ffbede5f40cca96f1580aaa2820e8b99dae989d94 debian-12.4.0-amd64-netinst.iso 155eb74ffe7344c895708a12672183c87a4dfc2e9faf4fa401a64cad212e6b7e debian-edu-12.4.0-amd64-netinst.iso 7f3eea6bf674584d9f162827a35d4bfd9e814513e88861315ce7526d1dded90f debian-mac-12.4.0-amd64-netinst.iso
And if you bought a "M"-keyed SSD, your ThinkPad T470s' "B"-keyed slot won't receive it.
Cf. https://superuser.com/a/1530488 [accessed 2024-01-27]
Most fascinatingly, setting "z-index: 0;" has an effect as its meddles with the stacking contexts and thus messes up situations in which children want to "position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: 1024;" but contend with siblings which are "position: sticky;".
$ go doc std.byte doc: no symbol byte in package archive/tar exit status 1
set -o pipefail shopt -s failglob set -u set -e
Most likely, a "io/fs".FS.Open'd directory does not implement "io/fs".ReadDirFile.
Cf. https://cs.opensource.google/go/go/+/master:src/io/fs/readdir.go;l=41;drc=a5943e9de13b050c20aa2490082206232af4615c [accessed 2024-01-17]
I think I've written about this before, but Vim's inability to not ignore backslash semantics for % are infuriating. I just wanted to delete the <br/>
tag with $d%!
(prime? .p) |> (not (any \<br/>
It appears that Go caches tests modulo comments which makes "// Output:" directives changing not invalidate the test cache ... :/
make([]string,0)!=nil holds. But apparently, make([]struct{},0x7fffffffffffffff) seldom panics.
When performing one singular change over a few commits (hard-resetting back down, making the change and cherry-picking back up), git tree-diff -p
is of great use:
$ git diff-tree c35d924 20af12a -p $ git diff-tree -p b202033 79f6768 $ git diff-tree -p 5565350 58db4e2 $ git reset --hard HEAD~1 && git push --force && git reset --hard 58db4e2a07b2c7388d1f213ce3debc8a05231039
Why does net/url ignore URL.RawPath if I explicitly set it?
$ cd "$(mktemp -d)" && cat >hrmpf.go <<'EOF' package main import ( "fmt" "net/url" ) func main() { fmt.Println((&url.URL{Scheme: "https", Host: "example.com", RawPath: "/i-ll-show-you-a-magic-trick-and-vanish"}).String()) } EOF $ go run hrmpf.go https://example.com
Funny, huh? One should only ever use "net/url".Parse. I never get URL construction by hand to work.
Bit me just now; an hour later I am convinced "compress/zlib" is a very old package and thus a tad inelegant. "compress/zlib".NewReader at least mentions in a comment how it may void data if r.(io.ByteReader) does not unearase. But "compress/zlib".(*Reader).Close writes something on second close (I get double closes since I employ a cautious, uncancelled "defer zwc.Close()").
master* $ go doc testing.t.fatal package testing // import "testing" func (c *T) Fatal(args ...any) Fatal is equivalent to Log followed by FailNow. master* $ go doc testing.t.failnow package testing // import "testing" func (c *T) FailNow() FailNow marks the function as having failed and stops its execution by calling runtime.Goexit (which then runs all deferred calls in the current goroutine). Execution will continue at the next test or benchmark. FailNow must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. Calling FailNow does not stop those other goroutines. master* $ go doc runtime.goexit package runtime // import "runtime" func Goexit() Goexit terminates the goroutine that calls it. No other goroutine is affected. Goexit runs all deferred calls before terminating the goroutine. Because Goexit is not a panic, any recover calls in those deferred functions will return nil. Calling Goexit from the main goroutine terminates that goroutine without func main returning. Since func main has not returned, the program continues execution of other goroutines. If all other goroutines exit, the program crashes.
Before rolling your own, use "math/bits".OnesCount64. There is also "math/bits".Len64.
Probably because of its dubious typing, I never before have used printf in Haskell. But writing a lot of Go has taught me its beauty.
ghci> import Text.Printf ghci> printf "%x\n" (2^63-1) 7fffffffffffffff
I just found out about strings.Field
. Since I often use strings.TrimSpace
, using something along the lines of strings.Split(s, " ")
just seems off (some people do use tabs). And regexp
feels overkill.
$ go test -memprofile=/tmp/mem.out ./... ... $ go tool pprof -http=:8081 /tmp/mem.out
Democratisation is a good thing. It dismantles awe people expressed for monumental tasks. But one should not forget that design is hard. The fallacy of inventing a new thing is ubiquitous. Why is it a fallacy? Because when you give up trying to fix a weak point in an existing system you most likely only shift this intrinsically difficult problem to another part of your new-fangled system. Which most likely is incompatible with the world and which is, quite frankly, why it is worth absolutely nothing.
I just had an unexplainable test results cache corruption---funnily enough, adding a " + 0" invalidates the cache, but e.g. adding " " inside a bracket map index does not.
$ go clean -testcache
In the past few weeks, "^Zgo doc ...\nfg\n" really has become a staple of my workflow. Reading https://pkg.go.dev/regexp@go1.21.5 [accessed 2023-12-16], I noticed that "go doc regexp/syntax" exists.
The following prints "closed" not once, but ad infinitum:
// Jonathan Frech, 2023-12-09 package main import "fmt" func main() { a := make(chan int) b := make(chan int) close(a) for { select { case _, ok := <-a: if !ok { fmt.Println("closed") } case <-b: } } }
master* $ openssl zlib -d <.git/objects/bf/074c0f6e7e72c82c98d466e008fa771cdf9915 | xxd | head 00000000: 626c 6f62 2031 3338 3731 3230 3634 0048 blob 138712064.H 00000010: 4541 4400 0000 0000 0000 0000 0000 0000 EAD............. 00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000070: 0000 0030 3030 3036 3434 0030 3030 3030 ...0000644.00000 00000080: 3030 0030 3030 3030 3030 0030 3030 3030 00.0000000.00000 00000090: 3030 3030 3237 0030 3030 3030 3030 3030 000027.000000000 error writing output file
curl -fsSL https://en.cppreference.com/w/cpp/symbol_index | grep '<tt>' | grep vector
$ set -x; cd "$(mktemp -d)" && git clone https://git.jfrech.com/~jfrech/brief.git repo && cd repo && packagetarget="$(grep -rI '^func Fuzz[A-Za-z0-9_]\+(f \*testing.F) {$' | sort -R | head -n1 | sed 's!^\([^:]*\)/[^:/]*:func \([A-Za-z0-9_]*\)(.*$!\1,\2!')"; GOPRIVATE=pkg.jfrech.com go test ./"${packagetarget%%,*}" -fuzz "${packagetarget##*,}"
path/filepath
too often.Quoting https://pkg.go.dev/path@go1.21.4
[accessed 2023-12-03],
Package path implements utility routines for manipulating slash-separated paths.
The path package should only be used for paths separated by forward slashes, such as the paths in URLs. This package does not deal with Windows paths with drive letters or backslashes; to manipulate operating system paths, use the path/filepath package.
Since I never respect Windows, I should probably not rely on path/filepath
to yield slash-delimited strings.
/Icon
filesMost likely a remnant of Mac OS 9's data/resource fork distinction.
# find . | grep '/Icon$' | while IFS= read -r icon; do rm "$icon"; done
Maybe I'll switch from Brave to Firefox ...
Cf. https://community.brave.com/t/turn-off-leo-completely-e-g-remove-all-visuals/514899 [accessed 2023-11-09]
Today I had a truly baffling bug in which brave-browser
simply would not start:
$ brave-browser [3290:3290:1105/015048.729334:ERROR:process_singleton_posix.cc(353)] The profile appears to be in use by another Brave process (6831) on another computer (p200300c2a70c1776cf4ec56b2b334f02.dip0.t-ipconnect.de). Brave has locked the profile so that it doesn't get corrupted. If you are sure no other processes are using this profile, you can unlock the profile and relaunch Brave. [3290:3290:1105/015048.729496:ERROR:message_box_dialog.cc(146)] Unable to show a dialog outside the UI thread message loop: Brave - The profile appears to be in use by another Brave process (6831) on another computer (p200300c2a70c1776cf4ec56b2b334f02.dip0.t-ipconnect.de). Brave has locked the profile so that it doesn't get corrupted. If you are sure no other processes are using this profile, you can unlock the profile and relaunch Brave.
It got so bad that I honestly installed Firefox ...
My fix was the following one-liner (especially the SingletonLock
seemed an issue):
find ~/.config/BraveSoftware/ | grep LOCK | while IFS= read -r LOCK; do rm "$LOCK"; done && rm ~/.config/BraveSoftware/Brave-Browser/SingletonLock
$ OUT=/tmp/x270 && rm -f ~/go/bin/fscs && GOPRIVATE=pkg.jfrech.com go install pkg.jfrech.com/glu/cmd/fscs@v0.0.0-20231104154721-209c09db5cb4 && ~/go/bin/fscs . >"$OUT" && find . | wc -l && wc -l "$OUT"
In analogy to the half-proverb "Accept interfaces, return structs." [citation needed], I think "Never accept an io.ReadCloser without returning one." should also be a proverb: initiating a second-layer network abstraction, as an example, potentially needs to read/write and close, closing on error. But else, the caller should be left as the closing entity.
I also realised how only returning structs idiomatically hints at not using a FailingReader, a concept I have now abandoned (one can hide two semantically different readers in the one io.Reader interface):
// preferred func Decode(encoding string, r io.Reader) (*DecodedReader, error) { if encoding != "base32" { return nil, fmt.Errorf("unknown encoding: %q", encoding) } return &DecodedReader{r: r}, nil } // to be avoided func Decode(encoding string, r io.Reader) io.Reader { if encoding != "base32" { return &FailingReader{fmt.Errorf("unknown encoding: %q", encoding)} } return &DecodedReader{r: r} } type FailingReader struct { Err error } func (fr *FailingReader) Read(p []byte) (int, error) { return 0, fr.Err }
net/mail.(*Address).String
does both encode and transport-encodeBit me the other day. To be fair, [the documentation](https://pkg.go.dev/net/mail@go1.21.3#Address.String) says "(...) will be rendered according to RFC 2047." RFC 2047 being atom encoding (or transport-encoding or Q/B-encoding).
Go 1.21.3 [says](https://pkg.go.dev/runtime/debug@go1.21.3#BuildSetting):
(...) CGO_ENABLED: the effective CGO_ENABLED environment variable CGO_CFLAGS: the effective CGO_CFLAGS environment variable CGO_CPPFLAGS: the effective CGO_CPPFLAGS environment variable CGO_CXXFLAGS: the effective CGO_CPPFLAGS environment variable CGO_LDFLAGS: the effective CGO_CPPFLAGS environment variable GOARCH: the architecture target (...)
I was scratching my head why CGO_CXXFLAGS
and CGO_LDFLAGS were aliases. After all, [Russ Cox had written it](https://cs.opensource.google/go/go/+/dadd80ae204bda1c3a48245d8a938f55f71259ea). How can you get more authoritative? But alas, it [was a bug](https://cs.opensource.google/go/go/+/43559aa9a5a550ba7dac224a174130e42f93de99).
Anyways, the key vcs.time
was what I truly searched for. Now I can programmatically encode the latest commit's date in [Brief](https://brief.software.jfrech.com/)'s manpage.
I know, I know: DNS does not propagate, what happens is that caches expire.
$ dig +short -t mx jfrech.com
$ go version && filename="$(mktemp)" && echo 'package main; import "strings"; func main() { strings.HasSuffix(strings, "") }' >"$filename.go" && go run "$filename.go" go version go1.20.8 freebsd/amd64 # command-line-arguments /tmp/tmp.ObFT1xQm.go:1:65: use of package strings not in selector
When regularily git add
ing or even git commit
ing followed by intrepid branch resetting and commit amending, it sometimes happens that one loses code one knows one wrote. When the last git gc --prune=now
is a while back, the following might aid in recovering these lines of code:
git fsck --dangling | grep '^dangling blob [0-9a-f]\{40\}$' | sed 's/dangling blob/git cat-file -p/' | xargs -I{} sh -c {} | vim -
.zfs/
I just now learnt of /zroot/.zfs/
, a pseudo directory in which all snapshots are pseudo-mounted. Very handy if you want to free up space by destroying a snapshot but maybe one directory which got deleted you really want to keep and re-examine later.
For the standard wired device em0
:
# grep em0 /etc/rc.conf ifconfig_em0="DHCP" ifconfig_em0_ipv6="inet6 accept_rtadv" # ed /etc/rc.conf ... # grep em0 /etc/rc.conf #ifconfig_em0="DHCP" ifconfig_em0="inet 192.168.2.98 netmask 255.255.255.0" ifconfig_em0_ipv6="inet6 accept_rtadv"
Cf. https://forums.freebsd.org/threads/setting-up-static-ip-address.46025/#post-257506
[accessed 2023-10-07]
Apparently, # scutil --set HostName host.name
. Cf. https://apple.stackexchange.com/a/287775
[accessed 2023-10-07]
# pwd && git show-ref && du -hs . && echo '=== FSCK' && git fsck --dangling | sort && echo '===' && git gc --no-prune --aggressive && du -hs . && echo '=== FSCK' && git fsck --dangling | sort && echo '==='
$ git fsck --dangling | sort | sha512sum $ git gc --no-prune --aggressive $ git fsck --dangling | sort | sha512sum
$ git push --delete origin v0.1.0
$ stat CHANGED_FILE ... $ git add CHANGED_FILE $ GIT_AUTHOR_DATE='2023-09-14 03:30:51 +0200' git commit -m '((actual commit message, authored from when the stale change was made, committer date is now))'
For some reason, my system time just offset itself by ~7h. To fix it, I had to manually ping a time server:
# ntpdate 0.pool.ntp.org 5 Oct 23:31:57 ntpdate[39118]: step time server 172.104.134.72 offset +60351.279198 sec
What did not work was a) restarting the NTP daemon via # service ntpd restart
; neither did b) restarting nor c) adjusting the timezone and disabling CMOS via # tzsetup
.
Cf. https://forums.freebsd.org/threads/time-is-always-wrong.83166/
[accessed 2023-10-05]
I bought a refurbished ThinkPad T470s (I manually removed camera, microphone and speakers). It had an OEM-installed Windows 10 on it (which I require for external reasons) and I wanted to dual-boot with Fedora 38. Inside Windows 10 running, I could shrink the boot partition and delete the recovery partition, but this lead to the computer no longer booting. Sticking in a Windows 10 installer thumb drive and powering the system on seems to have repaired the system.
% xcode-select --install
It must have been years ago, but this clothy, woolly background for me is the epitome of what a wallpaper is.
$ cd "$(mktemp -d)" && curl -fsSL https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/gnome-backgrounds/3.28.0-1/gnome-backgrounds_3.28.0.orig.tar.xz | tar -xz gnome-backgrounds-3.28.0/backgrounds/Fabric.jpg && mv */*/Fabric.jpg /tmp/fabric.jpg ; cd - >/dev/null
OSXFUSE or macFUSE [1] only implements deprecated FUSE 2, ships a slow SSHFS and is duly unreliable. To get rid of of this horrid macOS kernel extension, one has to both instruct it through the Control Panel to uninstall itself and [2] instruct Control Panel to remove the extension (third-party items have a context menu). Finally, % rm -rf Library/Caches/io.macfuse.preferencepanes.macfuse
.
REFERENCES. [1] https://osxfuse.github.io/ [accessed 2023-09-15] [2] https://www.imymac.com/powermymac/unistall-mac-fuse.html#part2 [accessed 2023-09-15]
# target=/usr/local/share/fonts/TTF/JetBrainsMono && [ ! -d "$target" ] && mkdir -p "$target" && usrtmpdir="$(mktemp -d)" && echo >&2 "$tmpdir" && cd "$tmpdir" && curl -fsSL https://download.jetbrains.com/fonts/JetBrainsMono-2.304.zip | unzip - && mv fonts/ttf/*.ttf "$target"/ && cd - >/dev/null && rm -rf "$tmpdir" && fc-cache -f && fc-list | grep -i jetbrains
Since I have of late managed to get a WiFi-enabled, FreeBSD-running, camera-and-microphone-removed ThinkPadX270 running, I began oncemore dabbling in dwm [1]. Surfing along, I came across the sh
line " weather=$(curl wttr.in?format=1)
" [2] whose blatant disregard for a POSIX shell's whitespace handling I could not leave untouched. Alas, creating a Gentoo wiki account seems to require running Gentoo, as the last step asks ''**To protect the wiki against automated account creation, we kindly ask you to answer the question that appears below ([more info](https://wiki.gentoo.org/wiki/Special:Captcha/help)):** | On a recent Gentoo system, what does `sed -n "6p" /etc/os-release | sha256sum | cut -d " " -f 1` print?'' [3]. Now, I do not have a machine running Gentoo and hashing the empty string or the string only containing a newline did not work. This is why only after three days I write these lines: I downloaded a three gigabyte gentoo-livegui-amd64-20230903T170202Z.iso
, put it on a thumb drive, tripped into KDE (ugh ... cf. [4]) and looked at the file in question:
gentoo@livecd ~ $ cat /etc/os-release NAME=Gentoo ID=gentoo PRETTY_NAME="Gentoo Linux" ANSI_COLOR="1;32" HOME_URL="https://www.gentoo.org/" SUPPORT_URL="https://www.gentoo.org/support/" BUG_REPORT_URL="https://bugs.gentoo.org/" VERSION_ID="2.14"
From the above, the correct 64 hex digits can be computed; I now have a Gentoo wiki account. Of course, I quickly logged out of my Gentoo live cd running that questionable desktop environment!
In a way, by search engines indexing my page, Gentoo wiki's security is hampered. I hope they will not now be robbed of their server resources.
I, however, do think that such forms of bot prevention are far more ethical than e. g. deploying tech giants' solutions and forcing your users to surrender their soul. The price Gentoo wiki pays is most likely a fairly low user count. But I am sure they are fine with that.
REFERENCES. [1] https://dwm.suckless.org/ [accessed 2023-09-12] [2] https://wiki.gentoo.org/wiki/Dwm#Custom_script [accessed 2023-09-12] [3] https://wiki.gentoo.org/index.php?title=Special:CreateAccount [accessed 2023-09-12] [4] https://blog.jfrech.com/271/ [accessed 2023-09-12]
I just noticed that when destroying a snapshot of a dataset which clings on to a lot of data, zfs list tank
called in quick succession reveals how the ZFS daemon takes its time to release captive blocks (which previously made me question which snapshot was to blame for the tank not releasing blocks I was sure not to be needed anymore -- the impatient do not see the full picture). But as [McK15, 41:19] said, ZFS' snapshotting efficiency is a function of churn. And a lot of data (even in the form of a singular, large file) means a lot of blocks which is churn.
REFERENCES
[McK15] Marshall K. McKusick: "An Introduction of the Implementation of ZFS", 2015. In: OpenZFS Conference 2015, San Francisco, California. Online: https://youtu.be/IQp_FglfzUQ?t=2479 [accessed 2023-08-28]
rsync
invocation$ rsync -vzP -caXN SRC/ DST/ $ rsync -vzP -caXN --delete SRC/ DST/
# chown -R root /root/.ssh && chmod 0700 /root/.ssh && chmod 0600 /root/.ssh/* # grep -v '^ssh-ed25519 [A-Za-z0-9+/=_-]\{68\}' /root/.ssh/authorized_keys # cat /etc/ssh/sshd_config PermitRootLogin prohibit-password PubkeyAcceptedKeyTypes=ssh-ed25519 PubkeyAuthentication yes UsePAM no KbdInteractiveAuthentication no ChallengeResponseAuthentication no PasswordAuthentication no PermitEmptyPasswords no X11Forwarding no PrintMotd yes #PrintLastLog yes ### not supported by FreeBSD 13.2-RELEASE
I am on a system where ssh
throws no hostkey alg
and have insufficient privileges to install host keys. So, to exfiltrate data, trusty nc
saves the day:
$ echo source system >/dev/null $ nc 192.168.2.119 6666 <DATA $ echo drain system >/dev/null $ nc -lp6666 >DATA
Of course, this is unencrypted and thus not cryptographically checksummed, so a final sha512sum
(or shasum -a512
on the Mac OS X 10.7.5 system I am currently on to read an old HFS (plus?) drive) must not be skipped.
On my space-constrained git VPS,
# du -hs /var/* ... 2.0G /var/log ...
was unacceptable. So I ran:
# journalctl --vacuum-time=1month ...
This got /var/log
down to 524760B. However, /usr/lib/modules
's 951488B I left untouched.
rsync
invocation$ rsync -calvzP
git/*
$ cd ~/git && ls | xargs -I{} git -C {} fetch
rsync
invocation$ rsync -calvz j@192.168.2.xxx:A /tmp/B
$ find "$DIR/" -type f | LC_ALL=C sort | xargs -L1 sha512sum | sha512sum
E. g. when fearing a prolonged Internet drought. (Which can happen if your University out of nowhere decides to scrap their root certificate which would expire ~2033 ($ openssl x509 -in wurzel.crt -inform DER -enddate -nocert
).)
$ for repo in ~/git/*; do git -C "$repo" fetch --all; done
$ wc -l "$TARGET_DIRECTORY"/* | grep '\<0\>' | awk '{ print $2 }' | xargs rm
I have to admit to using v1.3.0
instead of the more appropriate v2.0.0
solely to not get a varying import path.
$ GOPRIVATE=pkg.jfrech.com go install pkg.jfrech.com/imaptar/cmd/imaptar@v1.3.0 && echo "installed to: ${GOBIN:-${GOPATH:-$HOME/go}/bin}/imaptar"
Use case: One has a Git repository in which a file often changes and a directory of unmanaged backup files (simple copies). Worrying about losing data, the following is written:
$ for FILE in "$DIRECTORY"/*; do git cat-file 2>/dev/null -p "$(git hash-object "$FILE")" | cmp --quiet "$FILE" && rm "$FILE"; done
Slightly edited 2023-06-20.
# URL='https://go.dev/dl/go1.20.3.linux-amd64.tar.gz' CHECKSUM='979694c2c25c735755bf26f4f45e19e64e4811d661dd07b8c010f7a8e18adfca' ; [ "$(curl -f#SL "$URL" | tee /tmp/go.tar.gz | sha256sum | cut -d\ -f1)" = "$CHECKSUM" ] && rm -rf /usr/local/go && tar -C /usr/local -vxzf /tmp/go.tar.gz
Whilst developing brief, I noticed Go 1.20's new bytes.Clone
convenience function. It was enough to push me to update.
rsync
invocation$ rsync -cavz --delete root@jfrech.com:to-be-exfiltrated /tmp/exfiltrated
Since my VPS is running Debian 12 (bookworm) and I today decided to recompile my webserver which uses CGo to embed libbrotli on my Pop!_OS 22.04 LTS machine, glibc 2.31 did not cut the required versions 2.32 and 2.34. As such, I chose to pull testing packages on my public-facing webserver:
# tail -n1 /etc/apt/sources.list deb http://deb.debian.org/debian testing main
I find it an offence that ed
was not present on my machine. And somehow the above borked my machine to the extent that systemd-resolved.service
was suddenly missing and thus apt could not resolve deb.debian.org
.
My VPS (Debian 11.5) ran out of memory and had no zero bytes of swap set.
# swapon --show # fallocate -l 8G /swapfile # chmod 600 /swapfile # mkswap /swapfile Setting up swapspace version 1, size = 8 GiB (8589930496 bytes) no label, UUID=cd0d1bde-a291-4eea-9fc8-092e7a4062fd # swapon /swapfile
for m in 30 90; do for n in $(seq $((m)) $((m+7))); do printf '%2d \033[%dm########\033[m | \033[%dm \033[m\n' $n $n $((n+10)); done; [ $m -eq 30 ] && echo; done
$ echo '*** working tree' && git status --porcelain && echo -e '\n*** local' && git show-ref && echo -e '\n*** remote' && git ls-remote -q
Only the first of the following two Go programs compiles. Tested on Go 1.18--1.20.
package main; import "fmt"; func main() { if x := struct{}{}; true { fmt.Println(x) } }
package main; import "fmt"; func main() { type S struct{}; if x := S{} ; true { fmt.Println(x) } }
I just now realised the following:
$ export v=0 $ v=1 printf $v\\n 0 $ v=2 env | grep '^v=' v=2 $ v=3; printf $v\\n 3 $ v=4; env | grep '^v=' v=4
I. e. there is a discrepancy between processes interpreting the environment variables after a shell has spawned them and the shell itself subsituting variables when interpreting arguments.
$ v=4; v=5 v=6 echo $v v=7; echo v=8 $v v=9; env | grep '^v='
Cf. https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
Sometimes, skimming through git log
, I spot a typo only a few commits back in a repository I am fine force-pushing. in a commit message. The following shows a potential git lens workflow.
$ HEAD=$(git log --format=%H -1) && git stash -u # [!] loses staged/unstaged distinction $ git log --format=fuller --graph --all ... find COMMIT_TO_AMEND ... $ git reset --hard $COMMIT_TO_AMEND $ git commit --amend $ git cherry-pick $(git log --format=%H $COMMIT_TO_AMEND..$HEAD | tac | xargs) $ git log --format=fuller --graph --all ... verify ... $ git push --force && git stash pop
Cf. https://en.wikipedia.org/wiki/Bidirectional_transformation
In contrast to e. g. C++'s maps' operator[]
, go maps are not modified on read, making the naïve conception of maps as a concrete tree-like bit soup lead to the claimed behaviour.
Cf. https://groups.google.com/g/golang-nuts/c/HpLWnGTp-n8/m/hyUYmnWJqiQJ
Cf. https://en.cppreference.com/w/cpp/container/map/operator_at
I found the following test quite handy not to lose work.
$ git log --oneline -10 000000a (HEAD -> master) final-squashme 0000009 squashme 0000008 squashme 0000007 squashme 0000006 squashme 0000005 squashme 0000004 squashme 0000003 squashme 0000002 squashme 0000001 last-stable (origin/master, origin/HEAD) $ find . -type f | grep -v '^\./\.git/' | xargs sha512sum | sha512sum 000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - $ git reset --soft 0000001 $ find . -type f | grep -v '^\./\.git/' | xargs sha512sum | sha512sum 000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - $ echo "((sha512sum's outputs MUST match))" >/dev/null $ git commit -m new-stable [master 000000b] new-stable ...
For origin-double-checking, I like to use git log --all --graph
.
.eml
datesgrep -h '^Date:' -riI | sed 's/^Date: *//' | xargs -L1 -I{} -- date --date={} +'%Y-%m-%d %H:%M:%S' | sort
$ hd /dev/urandom | sed 's/^[^ ]* //; s/ |.*//; s/ //g; s/\(.\)/\1\n/g' | grep -v '^$' | head -n 12 | xargs echo | sed 's/ //g'
Only one fuzz test can be started, new interesting fuzzing arguments may be viewed via -test.fuzzcachedir
.
Cf. https://go.dev/security/fuzz/
[accessed 2023-01-26]
$ go test -fuzz=EncodedMailHeader -test.fuzzcachedir=/tmp/fcd
I today learnt that listening on localhost:8000
is not the same as listening on :8000
; the firewall is not to blame.
When reorganizing qep's project structure on disk, the following go toolchain bug tripped me up. Naturally, I abandoned work and focused on crystallizing it:
#! /bin/sh # Jonathan Frech, 2022-12-29 # A demonstration of a go toolchain bug: a malformed replace directive leaks # into unrelated error messages. set -e cd "$(mktemp -d)" && pwd cat >bugged-output <<'EOF' go version go1.19.3 linux/amd64 main.go:4:5: unknown@v0.0.0-00010101000000-000000000000: replacement directory /forbidden does not exist main.go:6:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:7:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:8:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:9:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:10:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:11:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:12:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:13:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory main.go:14:5: unknown@v0.0.0-00010101000000-000000000000 (replaced by /forbidden): reading /forbidden/go.mod: open /forbidden/go.mod: no such file or directory EOF go version && echo cat >go.mod <<'EOF' module main go 1.19 replace unknown => /forbidden require unknown v0.0.0-00010101000000-000000000000 EOF cat >main.go <<'EOF' package main import ( "unknown" "unrelated-0" "unrelated-1" "unrelated-2" "unrelated-3" "unrelated-4" "unrelated-5" "unrelated-6" "unrelated-7" "unrelated-8" ) EOF go build
A month ago, I wrote a factoid about fusing git repositories using git cherry-pick
. This of course modifies the committer's date (though at least keeps the author's date intact!). Today I discovered that git merge --allow-unrelated-histories
is a more apt choice for combining parts of a project that co-evolved in separate repositories:
$ git remote -v $ cd ~/git $ git clone git@git.jfrech.com:~jfrech/crooked-with-a-pearl.git ... $ cd crooked-with-a-pearl $ mkdir pearl $ ... extract, refactor slightly and prepare for transferal ... $ ... such that only .git and pearl remain as top-level directories ... $ git add . && git commit -am 'preparing for transferal' ... $ git push ... $ cd ~/git/shiny $ git remote -v ... $ git remote add transferal git@git.jfrech.com:~jfrech/crooked-with-a-pearl.git $ git remote -v ... $ git fetch transferal $ [ ! -e pearl ] && git merge --allow-unrelated-histories transferal/master ... $ [ -d pearl ] && git remote remove transferal $ git remote -v $ git log --graph ... $ git push ...
qpdf
No, I am not talking about the convolution of probability density functions; I am talking about the unfortunetely standard format for information-interchange of physical-paper-imitating data BLOBs:
qpdf --empty --pages *.pdf -- combined.pdf
Ref. https://stackoverflow.com/a/53754681
[2022-12-10]
I thought about defining a code golf taks in terms of properties of the source code and its reverse. Yet immediately one notes that few languages exhibit (pseudo-)palindromic keywords, most of them (i.e. APL or golfing languages) only one-character long ones. Thus the second idea was to adhere to (pseudo-)palindromicity over the line ordering, yet a C-style snippet alike
#define FORWARDS 1 int main() { puts(FORWARDS ? "f" : "-f"); } #define FORWARDS 0
swiftly outs this idea as unfruitful.
defer
and panic
gotchaI just read the other night, how [A] deferred [function] will run even if the critical section panics [...]
[DK16]. Still, a setting distillable to the following had me contemplating reality:
package main import "os" func main() { defer os.Exit(0) panic("won't fire") }
[DK16] Alan A. A. Donovan, Brian W. Kernighan: The Go Programming Language. Addison-Wesley, 2016. ISBN-13: 978-0-13-419044-0
$ cd "$DESTINATION_REPO" $ git remote add FUSE "$SOURCE_REPO" $ git fetch FUSE $ git cherry-pick f0f0c1bba79d28bc36e0ca1dae22c80a8e8f8349 ... fixup ... $ git remote remove FUSE
xxd /dev/urandom | sed 's/^[0-9]*: //; s/ .*$//; s/ //g; s/\(.\)/\1\n/g;' | sed '/^$/d' | head -n40 | xargs echo | sed 's/ //g'
# URL='https://go.dev/dl/go1.19.3.linux-amd64.tar.gz' CHECKSUM='1bf389df6d7efa6b54b04332c70356ee0d133753b1e58753e80ebafcff0f559c61223ddad3f5d024f0c538dbbd7d6ac92abb6b022f6a171a91a5ef39b0d82c9b' ; [ "$(curl -f#SL "$URL" | tee /tmp/go.tar.gz | sha512sum | cut -d\ -f1)" = "$CHECKSUM" ] && rm -rf /usr/local/go && tar -C /usr/local -vxzf /tmp/go.tar.gz
T{0,}.f(), T{0x1,}.f()
A long-standing (over a year!) validator bug has finally been resolved: https://github.com/validator/validator/issues/1166
; I mailed Henri Sivonen to fix his HTML parser, but apparently my surmised root cause of this validator behaviour was wrong. Anyways, I am glad to be able to use color-scheme
-dependant theme-color
s without upsetting the validator.
A bit worryingly, FreeBSD 14's installer complained about a base.txz
checksum mismatch (using the ftp://fpt5.de.freebsd.org
mirror).
# TARGET=/dev/sdX SOURCE_XZ='https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/13.1/FreeBSD-13.1-RELEASE-amd64-mini-memstick.img.xz' SOURCE_SIZE='455889408' SOURCE_DIGEST='a519326bb0fcce5da4b86eb202894baafe12aa4f2d226c90f8db45aece731d0e54914340be84a2986c40fca81cc80b1bd6c21b0c3d9c0d25401c82ed9d2f756b' && [ "$SOURCE_DIGEST" = "$(curl -fsSL "$SOURCE_XZ" | xz -d | tee "$TARGET" | sha512sum | cut -d\ -f1)" ] && sync -f && [ "$SOURCE_DIGEST" = "$(head -c"$SOURCE_SIZE" "$TARGET" | sha512sum | cut -d\ -f1)" ] && echo success || echo corrupted
I today tried Guix, but I cannot get it to work without using a login manager, a category of software I despise. As such, the dreams of an FSF compliant and ethically sound GNU/Linux OS broken, I will turn my back on Linux.
# TARGET=/dev/sdX SOURCE_XZ='https://download.freebsd.org/snapshots/amd64/amd64/ISO-IMAGES/14.0/FreeBSD-14.0-CURRENT-amd64-20220930-42dc8696df5-258315-mini-memstick.img.xz' SOURCE_SIZE='499175936' SOURCE_DIGEST='780c92bbb6d3eb0d49d5f3c7061e4b4cd5ac33a3ec12404918491568e40dd21987298a0cbbfc592c07bae6eebf2fd0938fa2ad2a27330a0d69923671e7652c94' && [ "$SOURCE_DIGEST" = "$(curl -fsSL "$SOURCE_XZ" | xz -d | tee "$TARGET" | sha512sum | cut -d\ -f1)" ] && sync -f && [ "$SOURCE_DIGEST" = "$(head -c"$SOURCE_SIZE" "$TARGET" | sha512sum | cut -d\ -f1)" ] && echo success || echo corrupted
gnome-disks
I am ashamed to admit it: I am currently in possession of an electron-based brain employing Redmond malware in its tenth incarnation. However, I am at present, progressively, in the act of fleeing. Since I air-gapped the system and still want to extract remnants of what I did in the filthy times of old, I opted for a thumb drive. Mine being populated by Pop!_OS' installer, I needed to format it, preferably to a FATty type. Therein lied the trouble: I do not exactly know what I did wrong (possibly too excitetly unplugging or deleting the partition table one too many times), but neither Windows' formatter nor gparted
were able to cope with my thumb drive's state. To the rescue came gnome-disks
with its Debian 11 package called gnome-disk-utility
. Though I am an avid GUI denier, I still format my drives in a clicky manner and GNOME's utility is both better designed than my previous two choices from an UX and aesthetic point of view and actually did the deed.
After yesterday's agonizing encounters with go's build system:
go: downloading pkg.jfrech.com/go/webutils v0.0.0-20221004154235-906e87a86844 webserver-binary imports page/dpfs_jfrech_com: pkg.jfrech.com/go/webutils@v0.0.0-20221004154235-906e87a86844: invalid version: unknown revision 906e87a86844
I today had the epitome that possibly my splendid habit of git comment -a --amend && git push --force
could be at fault.
Deleting all go.sum
files and everything below every go.mod
's go version declaration, GOPROXY=direct GOSUMDB=off go mod tidy
got ahold of my ordeal.
html.spec.whatwg.org
and validator.w3.org
inconsistencyI found this behaviour the other day (
); cannot report it as the validator does not throw an error, merely a warning.Warning: Consider using the h1 element as a top-level heading only (all h1 elements are treated as top-level headings by many screen readers and other tools). ; From line 21, column 17; to line 21, column 20 ; <h1>Naviga
validator.w3.org
bugI would argue that this use of <meta name="theme-color" ... />
is valid and should not error.
Ref. https://github.com/validator/validator/issues/1166
Ref. https://github.com/validator/validator/issues/1424
url(...)
is relative to the CSS source file, even when it is a data URIAfter hours of work, I had converted knôtM 3 to using self-managed fonts and including them via a stylesheet represented by a data URI. After that, I was stumped for a while why no fonts loaded: using a url(/...)
with an absolute path but relative host
, I had specified a relative host to no URL, but an anonymous data URI. As so often, it is blatently obvious that this approach could never have worked.
Conclusio: Specify a full URL (or URI, but base64-encoding fonts incurs 4/3 data usage as well as probably breaking both the font and glyph cache) when using @font-face
to include fonts from an anonymous, abstract place of pure data.
do { let _ = undefined; return () }
go tool dist env | grep -P '^(GOARCH|GOOS)'
I would use `... | hex -d | base64`, yet -- to me bewilderingly -- `hex` does not exist. With the below approach of note is the double-escaped \
which forms printf
character escape sequences: not for the shell, once for sed
and once for xargs
.
... | sha512sum | cut -d\ -f1 | sed 's/\([0-9a-f]\{2\}\)/\\\\x\1/g' | xargs printf | base64 -w0
xxd /dev/urandom | grep -oP '(?<=: )[0-9a-f ]*(?= )' | sed 's/ //g' | grep -oP '^.{12}' | head
.NEF
to some renderable representationfor nef in *.nef; do dcraw -c -w "$nef" | convert ppm:- "${nef%.nef}.jpg" && echo >&2 "$nef"; done
Ref. https://www.dechifro.org/dcraw/
It is written text/plain; charset=utf-8
, not text/plain; encoding=utf-8
.
Hosted by the FSF: https://directory.fsf.org/wiki/License:Expat
.
$ ssh-keygen -lf ~/.ssh/known_hosts $ ssh-keygen -lf ~/.ssh/known_hosts -F jfrech.com
# [ "$(curl -f#SL 'https://download.freebsd.org/releases/arm64/aarch64/ISO-IMAGES/13.1/FreeBSD-13.1-RELEASE-arm64-aarch64-RPI.img.xz' | tee /tmp/freebsd.img.xz | sha512sum | cut -d\ -f1)" = '761ca4f17da9b0da8a8b6418d0463152ba16147022b15549d7c8b1c3020a2f89c7d56c04cbc9bc1c5ec54dd4f563f7289313526aa0287e0afc43ecabd0f6e2f8' ] && xz -d /tmp/freebsd.img.xz && dd if=/tmp/freebsd.img of=/dev/sdb status=progress conv=fsync bs=4M && sync -f
Root's password is root
.
echo "${1:-$HOME/.config}"
It supposedly fixed a file descriptor starving problem. Also, I wanted to use `encoding/xml`'s `func (d *Decoder) InputPos() (line, column int)`.
[ -w /usr/local ] && [ "$(curl -fsSL 'https://go.dev/dl/go1.19.linux-amd64.tar.gz' | tee /tmp/go.tar.gz | sha256sum | cut -d' ' -f1)" = '464b6b66591f6cf055bc5df90a9750bf5fbc9d038722bb84a9d56a2bea974be6' ] && rm -rf /usr/local/go && tar -C /usr/local -xzf /tmp/go.tar.gz && rm -f /tmp/go.tar.gz
$ ssh-keygen -t ed25519 -f"$HOME"/.ssh/tempkey -N '' -C "delete one day after $(date)" $ ssh-keygen -lf ~/.ssh/tempkey
# [ -w /usr/local ] && [ "$(curl -fsSL 'https://go.dev/dl/go1.18.3.linux-amd64.tar.gz' | tee /tmp/go.tar.gz | sha256sum | cut -d' ' -f1)" = '956f8507b302ab0bb747613695cdae10af99bbd39a90cae522b7c0302cc27245' ] && rm -rf /usr/local/go && tar -C /usr/local -xzf /tmp/go.tar.gz && rm -f /tmp/go.tar.gz && echo 'successfully installed go1.18.3.linux-amd64'
git
's operationGIT_CURL_VERBOSE=1 GIT_TRACE=1 git clone https://git.jfrech.com/not-yet-implemented
Especially if tikz drawings jump unanchordly all over the page, running the backend again might jiggle everything in place. I wasted an undisclosed amount of hours doubting digital reality yesterday. (For bilbiographical references or indexes, a third run could even be necessary.)
# curl -f#SL https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/13.1/FreeBSD-13.1-RELEASE-amd64-mini-memstick.img >/dev/sdb && sync -f
for f in *; do [ "$(sha512sum "$f" | cut -d' ' -f1)" = "$f" ] || echo FAILURE "$f"; done
sbt
on Debian# bin='/usr/local/bin' ; [ ! -d "$bin"/sbt.pkg ] && { mkdir -p "$bin" && rm -rf /tmp/installing-sbt && mkdir -p /tmp/installing-sbt && curl -fsSL https://github.com/sbt/sbt/releases/download/v1.6.2/sbt-1.6.2.tgz | tar -C /tmp/installing-sbt -vxz && mv /tmp/installing-sbt/sbt "$bin"/sbt.pkg && rm -rf /tmp/installing-sbt && cd "$bin" && ln -sf sbt.pkg/bin/sbt ;} || echo aborting
In Go 1.17, the following exclaims assignment mismatch: 2 variables but 1 value
before noticing undefined: y
. Go 1.18 does away with the rather unhelpful first message.
package main; func main() { x, ok := map[int]int{}[y] }
What bit me today was -XCPP
being dominant to -XQuasiQuotes
(template haskell), meaning any DSLs not fixed under preprocessing will be meddled with -- resulting in nigh unpredictable outcomes.
Incriminating myself, I will admit that I do own a solid-state drive with a bootable and licensed copy of Windows 10. Yet, wanting to attempt to fix a bluetooth speaker's firmware, I yesterday was met with a nonstarting Windows with its recovery tool unable to help. Potentially replugging my four external drives and disc drive confused the Windows bootloader, yet after examining the partition using # mkdir MNT && mount /dev/sdd3 MNT
, I was met with a frightening message similiar to this one. The most amusing part of this story -- I find -- is how the mount
tool on Debian was able to explain to me what I had to do in Windows' recovery console: chkdsk /f C:
-- it worked flawlessly and I could install Bose's evil spyware inside a bare-metal running massive hunk of spyware. Yet, the speaker is no longer supported so all efforts where at last in vein.
Although it happens seldomly, when I define an integer constant in a module which does not enforce any further type requirements and want to use it in another module in the context of an Int
-- for example (5 <) $ OtherModule.n
-- the integer constant is unchangeably typed an Integer
. I see how it would be difficult to type-infer across already compiled object files (and the implications for dependent object files with possibly type clashes throughout), yet the occasional irritation remains. I find sprinkling type annotations :: Int
the most immediately useful.
Amazed by discovery: Instead of fumbling $ printf '%s\n%s\n' "$a" "$b"
, a wiser approach may be $ echo $"$a\n$b"
.
[2022-03-29] I noticed this shell's capability whilst reading Allan Odgaard's post macOS 10.15: Slow by Design. See also the bash manual (do not fret; $'...'
appears not to be a bashism).
Quickly inside an editing session:
:syntax region TemplateHaskellQuasiQuote start='\[[a-z][a-zA-Z0-9_']*|' end='|\]' | highlight link TemplateHaskellQuasiQuote Comment
As an autocmd
:
autocmd FileType haskell syntax region TemplateHaskellQuasiQuote start='\[[a-z][a-zA-Z0-9_']*|' end='|\]' | highlight link TemplateHaskellQuasiQuote Comment
I also do not like how xxxx
and 4x
behave differently when at the end of a line:
wakka wik-wuk ^ `xxxx` results in: wakka wik
wakka wik-wuk ^ `4x` results in: wakka wik-wu
Especially when writing Haskell, I routinely get momentarily magnificently irritated by the "feature" that an "escaped" parenthesis does count towards matching parenthesis highlighting yet not towards %
-jumping:
sortRecords = sortOn (\(Record { value1, value2 } -> f value2 value1)) -- ^ when pressing `%` here, you jump to there ------^ -- ^ pressing `%` fails here
ls
ls -d
Ref. https://www.linuxquestions.org/questions/linux-newbie-8/using-%27ls%27-to-list-only-the-current-directory-543135/#post2696628
$ rsync old/ new
$ echo 'V=". ."; echo $V' | bash . . $ echo 'V=". ."; echo $V' | zsh . .
# DEVICE='/dev/sde' ; lsblk ; curl -f#SL 'https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.2.0-amd64-netinst.iso' -o /tmp/debian.iso && [ "$(sha512sum /tmp/debian.iso | cut -d' ' -f1)" = 'c685b85cf9f248633ba3cd2b9f9e781fa03225587e0c332aef2063f6877a1f0622f56d44cf0690087b0ca36883147ecb5593e3da6f965968402cdbdf12f6dd74' ] && dd if=/tmp/debian.iso of="$DEVICE" bs=4M conv=fsync status=progress
find <dir/> -type f | sed "s/^/'/; s/$/'/" | xargs -L1 sha512sum | sort
$ xwininfo -root | grep '^ \(Width\|Height\): [1-9][0-9]*$' | sed 's/.*: //' | tr '\n' 'N' | sed 's/N$/\n/; s/N/x/'
<meta id="wakka" name="theme-color" content="#f90000"> <script><!-- function clr(r, g, b) { function f(n) { hex = (n & 0xff).toString(16); while (hex.length < 2) hex = '0' + hex; return hex }; document.getElementById('wakka').content = '#' + f(r) + f(g) + f(b); }; async function f() { for (var j = 0; j < 250; ++j) { await new Promise(r => setTimeout(r, 10)); clr(j, 0, 0); } }; f(); --></script>
date --date="@$(date +%s)"
I just began tinkering with golang.org/x/crypto/ssh
and find their reverse proxy capabilites amazing: when allowing the VPS' ssh deamon's GatewayPorts
option
# sed --in-place /etc/ssh/sshd_config 's/^#GatewayPorts no$/GatewayPorts yes/' && systemctl restart sshd
the following go code can be run on a local machine, hooking this machine into the global network where the VPS resides:
// Jonathan Frech, 2022-01-02 // on the VPS' side: // # sed --in-place /etc/ssh/sshd_config 's/^#GatewayPorts no$/GatewayPorts yes/' && systemctl restart sshd package main import ( "fmt" "io/ioutil" "log" "net/http" "os" "path/filepath" knownhosts "golang.org/x/crypto/ssh/knownhosts" ssh "golang.org/x/crypto/ssh" ) func main() { privkeypath := "id_rsa" dotsshpath := filepath.Join(os.Getenv("HOME"), ".ssh") serveraddress := "jfrech.com:22" privkey, err := ioutil.ReadFile(filepath.Join(dotsshpath, privkeypath)) if err != nil { log.Fatalf("could not read private key: %v", err) } signer, err := ssh.ParsePrivateKey(privkey) if err != nil { log.Fatalf("could not parse private key: %v", err) } hostKeyCallback, err := knownhosts.New(filepath.Join(dotsshpath, "known_hosts")) if err != nil { log.Fatalf("could not build hostKeyCallback: %v", err) } config := &ssh.ClientConfig{ User: "root", Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, HostKeyCallback: hostKeyCallback, } client, err := ssh.Dial("tcp", serveraddress, config) if err != nil { log.Fatal("could not dial: %v", err) } defer client.Close() l, err := client.Listen("tcp", "0.0.0.0:80") if err != nil { log.Fatalf("no tcp forward: %v", err) } defer l.Close() http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Bin ich schon drin?") })) }
One may use # netstat -tlnp
on the VPS' side to check ssh's gateway setting; 127.0.0.1:80
is a bad sign since the reverse proxy will not be accessible from outside the VPS' local address. 0.0.0.0:80
is what one wants to see (a very permissive mask).
Currently, https://pkg.go.dev/net/http#Response
reads in part
// Uncompressed reports whether the response was sent compressed but // was decompressed by the http package. When true, reading from // Body yields the uncompressed content instead of the compressed // content actually set from the server, ContentLength is set to -1, // and the "Content-Length" and "Content-Encoding" fields are deleted // from the responseHeader. To get the original response from // the server, set Transport.DisableCompression to true. Uncompressed bool
Should it not say content actually sent from the server
?
For nearly two weeks now, I own a refurbished ThinkPad. And whilst I am configuring dwm on my new portable machine, I tried myself at a concise awk expression to prove my red nub commitment.
xinput set-prop "$(xinput list | gawk '/Synaptics TM3075-002/ { match($0, /id=([0-9]*)/, arr); print arr[1] }')" 'Device Enabled' 0
fileR, err := os.Open(filename) /* equivalent to: `os.OpenFile(filename, os.O_RDONLY, 0)` */ fileW, err := os.OpenFile(filename, os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0644) /* note: `os.Create(filename)` is equivalent to `os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)`, opening in read-write mode and giving everyone read-write permissions /* see also: https://pkg.go.dev/os#pkg-constants */
case
case "$(uname)" in Darwin) echo 'Why not use a really free FreeBSD?' ;; *) echo 'non-specific uname' ;; esac
# [ $(id -u) = 0 ] && rm -rf /bin/go && curl -f#SL https://dl.google.com/go/go1.17.2.linux-amd64.tar.gz | tar xz -f - -C /bin && printf 'now add /bin/go/bin to your $PATH\n'
https://play.golang.org/p/kv34cASB_0k
systtetmctl halt
Since Debian is only mainline-Linux and proprietary-possible nonfree, I decided to give it another try as my daily driver.
# [ -n "$(id -u)" ] && lsblk && printf 'flash to /dev/' && read DEVICE && lsblk | grep "^$DEVICE" && URL_IMAGE='https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.0.0-amd64-netinst.iso' && URL_CHECKSUMS='https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA512SUMS' && [ "$(curl -f#SL "$URL_IMAGE" | tee /tmp/debian.iso | sha512sum | cut -d' ' -f1)" = "$(curl -fsSL "$URL_CHECKSUMS" | grep "^[0-9a-f]\{128\} ${URL_IMAGE##*/}$" | cut -d' ' -f1)" ] && dd if=/tmp/debian.iso of=/dev/"$DEVICE" bs=64K conv=fsync status=progress && sync
Over the past few days I have dreamt of a Guix running on a microSD card on my Pinebook Pro. After I yesterday bought a USB C to Cat adapter (ICY BOX IB-AC535-C), it finally takes shape.
I used the following Guix SD raw image: https://ci.guix.gnu.org/search/latest/image?query=spec:images+status:success+system:x86_64-linux+pinebook-pro-barebones-raw-image
... login as root, no password set ... # cfdisk /dev/mmcblk1 ... resize /dev/mmcblk1p1 to the full remaining size ... # resize2fs /dev/mmcblk1p1 # ip link set eth0 up && dhclient # guix pull
$ mv /tmp/random.data "$(head -c 1000000000 /dev/urandom | tee /tmp/random.data | sha512sum | cut -d' ' -f1)".data
# lsblk ; read ; DEVICE=/dev/sdd ; ISO='void-live-x86_64-musl-20210218.iso' ; ISO_TEMP='/tmp/voidlinux.iso' ; [ "$(curl -f#SL "https://alpha.de.repo.voidlinux.org/live/current/$ISO" | tee "$ISO_TEMP" | sha256sum | cut -d' ' -f1)" = "$(curl -fsSL 'https://alpha.de.repo.voidlinux.org/live/current/sha256sum.txt' | grep "^SHA256 ($ISO) = [0-9a-f]\{64\}\$" | cut -d' ' -f4)" ] && printf 'successfully downloaded and verified hash: %s\n' "$ISO_TEMP" && dd if="$ISO_TEMP" of="$DEVICE" bs=16K status=progress
# lsblk | grep sdd ; printf 'Download parabola and burn it to /dev/sdd? (Enter or SIGINT) ' ; read && curl -fsSL https://redirector.parabola.nu/iso/x86_64-systemd-lxde-2019.06-pre/parabola-x86_64-systemd-lxde-2019.06-pre-complete.iso | dd if=/dev/stdin of=/dev/sdd bs=16M
$ curl -fsSL https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-05-28/2021-05-07-raspios-buster-armhf-lite.zip | gunzip - -c | sudo dd if=/dev/stdin of=/dev/sde bs=4M conv=fsync
Ubuntu did not work; possibly because I am using a Pi Zero (which appears to be equivalent to B+ image-wise)
$ curl -f#SL https://cdimage.ubuntu.com/releases/21.04/release/ubuntu-21.04-preinstalled-server-arm64+raspi.img.xz | xz -d > rp.img && sudo dd if=rp.img of=/dev/sde bs=1M status=progress
/usr/share/vim/vim82/syntax/
ansiclr
Since I no longer install my own jtool, the following one-liner is now useful.
$ curl -fsSL https://raw.githubusercontent.com/jfrech/jt/master/toolbox/ansiclr/ansiclr.c | gcc -x c - -o /tmp/ansiclr && /tmp/ansiclr
The below invocations do not work. Apparently one has to do more than dd
the image (ref. https://www.freshports.org/sysutils/u-boot-pinebookpro/
; ref. https://ftp.openbsd.org/pub/OpenBSD/snapshots/arm64/INSTALL.arm64
)
# curl -f#SL 'https://download.freebsd.org/ftp/releases/arm64/aarch64/ISO-IMAGES/13.0/FreeBSD-13.0-RELEASE-arm64-aarch64-PINEBOOK.img.xz' | xz -d - > /tmp/pbp.img && dd if=/tmp/pbp.img of=/dev/sde status=progress bs=64K # curl -f#SL 'https://personalbsd.org/images/FreeBSD-aarch64-13.0-RELEASE-Pinebook-Pro-20210720.img.xz' | xz -d - > /tmp/pbp.img && dd if=/tmp/pbp.img of=/dev/sde status=progress bs=64K
Since I am now heavily invested into Guix and the GNU ecosystem, I decided to write a bash prompt.
# Jonathan Frech, 2021-09-28 # a minimalistic two-line bash prompt; uses Unicode characters export PROMPT_COMMAND='[ -f /tmp/fl ] || (echo LyogSm9uYXRoYW4gRnJlY2gsIDIwMjEtMDktMjggKi8KLyogZmwsIGZpbGwgbGluZSAtLSBmaWxsIHRoZSB3aG9sZSBsaW5lIHdpdGggZmFpbnRseQogICBjb2xvcmVkICdib3ggZHJhd2luZ3MgbGlnaHQgaG9yaXpvbnRhbCcgY2hhcmFjdGVycwogICAoZGVjaW1hbCBVbmljb2RlIGNvZGUgcG9pbnQgOTQ3MikgKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KCmludCBtYWluKCkgewogICAgc3RydWN0IHdpbnNpemUgdzsKICAgIGlvY3RsKFNURE9VVF9GSUxFTk8sIFRJT0NHV0lOU1osICZ3KTsKCiAgICBwcmludGYoIlwzM1tHXDMzWzkwbSIpOwogICAgZm9yIChpbnQgaiA9IDA7IGogPCB3LndzX2NvbDsgKytqKQoJICAgIHByaW50ZigiXHhlMlx4OTRceDgwIik7CiAgICBwcmludGYoIlwzM1ttIik7Cn0K | base64 -d - > /tmp/fl.c && gcc -O3 /tmp/fl.c -o /tmp/fl) ; printf "\33[90m\xe2\x80\xa2\33[m\n" && /tmp/fl' export PS1='\[\e[G\e[90m\]╭────── \[\e[m\]\w\[\e[90m\] ─── \u@\h ─── \D{%Y-%m-%d %H:%M:%S} \[\e[m\]\n\[\e[90m\]╰─ \[\e[m\e[$((92-!!$?))m\]\$\[\e[m\] '
Now I can use lsblk
instead of FreeBSD's geom disk list
.
$ guix install curl $ lsblk $ sudo su # curl -f#SL https://ci.guix.gnu.org/search/latest/ISO-9660?query=spec:images+status:success+system:x86_64-linux+image.iso -o /tmp/guix.iso && dd if=/tmp/guix.iso of=/dev/sdd status=progress bs=64K
# curl -f#SL https://ftp.gnu.org/gnu/guix/guix-system-install-1.3.0.x86_64-linux.iso -o guix.iso && dd if=guix.iso of=/dev/da0 status=progress bs=64K
dig
using apt
# apt install dnsutils
Since Debian's packages are so unbelievably outdated (go1.15.9
on a fresh installation of Debian 11 Bullseye), I have moved to installing binaries by hand.
rm -rf /bin/go /usr/local/go && mkdir -p /usr/local/go && curl -fsSL https://golang.org/dl/go1.17.1.linux-amd64.tar.gz | tar -C /usr/local -xz && ln /usr/local/go/bin/go /bin/go
date -r "$(date +'%s')" +'%Y-%m-%d_%Hh%Mm%Ss'
Even though I am aware of ${var%pat}
, ${var%%pat}
, ${var#pat}
and ${var##pat}
I still cannot remember which expression does which and always have to look it up. The trouble is, looking this feature up is no easy feat as it as far as I know has no distinctive name. As such, I have reproduced its documentation:
${var%pat} remove the shortest match from the right ${var%%pat} remove the longest match from the right ${var#pat} remove the shortest match from the left ${var##pat} remove the longest match from the left
As such, to get a filepath's parent directory one may use ${var%/*}
and to get its filename ${var##*/}
. Running the shell script
#! /bin/sh fp=/parent/path/file echo "$fp" echo "${fp%/*}" echo "${fp##*/}"
produces:
/parent/path/file /parent/path file
Ref. https://tldp.org/LDP/abs/html/parameter-substitution.html#PARAMSUBREF
Consoluting the handbook (https://docs.freebsd.org/en/books/handbook/bsdinstall/#bsdinstall-usb
), the following may be advisable:
dd if=FreeBSD-13.0-RELEASE-amd64-memstick.img of=/dev/da0 bs=1M conv=sync && sync
For a long time, I have used balenaEtcher to flash bootable thumb drives on my MacBook. Yet I feel it is incredibly bloated. Thus I started to dd
the image directly. lsblk
or diskutil list
are useful companions.
% thumbdrive='/dev/disk2' ; image='FreeBSD-13.0-RELEASE-amd64-mini-memstick.img' ; sudo dd bs=64k if="$image" of="$thumbdrive" && sudo head -c "$(wc -c "$image" | cut -d' ' -f2)" /dev/disk2 | cmp "$image" && echo 'successfully flashed thumb drive'
% lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS ... sde 8:64 1 121.3M 0 disk ... % sudo dd if=/dev/urandom of=/dev/sde status=progress ibs=1 obs=1
find . | grep '\.jpg$' | while read f; do d="$(dirname "$f")"; b="$(basename "$f")"; mv "$f" "$d/$(identify -format '%[EXIF:DateTime] %wwx%hh' "$f" | sed 's/:/-/g; s/ /_/g')_$b"; done
Unfortunately, Manjaro no longer supports brave as a main pacman package. As such, it is probably most convenient to install it via paru (formerly yay). Since paru is not and most likely never will be in any official pacman repository, its installation is a bit more involved:
% tmp="/tmp/$(uuidgen)" && mkdir -p "$tmp" && cd "$tmp" && git -C "$tmp" clone https://aur.archlinux.org/paru.git && cd "$tmp/paru" && (makepkg -si || echo 'Have you run `# pacman -S base-devel`?') && paru -S brave-bin
% curl -s http://www.netzmafia.de/software/wordlists/deutsch.txt | grep -i '[aeiou]\{4\}' --color=always
vim
stylingDefault color schemes can be found under /usr/share/vim/vim??/colors
. I plan to create a minimalistic, low color depth scheme.
Since Guix feels to bloated and iffy, I plan to move back to Manjaro. Yet I would like to use XMonad as my window manager. A few months or years ago, one was able to perform a guided non-graphical installation using Manjaro architect; this ISO has disappeared from manjaro.org
yet is available on the experimental subdomain: https://hacked.manjaro.org/download/#architect
. I am unsure if this ISO is up to date and/or it can be easily upgraded to a recent state.
I did however read that the XFCE ISO has an architect option. I will try this route before installing a potentially stale ISO. [2021-06-25] After having booted the XFCE ISO, I dug further and realized that Manjaro architect has been dropped as a project. What a shame.
Curiously, after having installed Parabola once and scrambled its keys, unable to recover since pacman
did not even manage to install keys, I could not get Parabola to boot after GRUB. I now tried to install the boot loader under /
and it worked! (I am currently using the bloated GUI install; https://wiki.parabola.nu/Get_Parabola#Parabola_SystemD_LXDE_ISO
.) Apparently, two days ago the mirror switch redirected me to a flaky mirror and muddling with the mirror list manually made pacman
lose confidence. Anyhow, a pacman -Syyu
took a bit and https://wiki.parabola.nu/Installation_Guide#Verification_of_package_signatures
's recommendation of installing pacman -Sy archlinux-keyring archlinuxarm-keyring parabola-keyring
reduced the number of missing keys to one.
Annoyingly, some mirrors seem to be offline, leading to a error: failed to retrieve file '...' from redirector.parabola.nu : Operation too slow. Less than 1 bytes/sec transferred in the last 10 seconds
.
I have not yet resolved the missing key issue and am left unable to update my system; one wiki thread I found is https://labs.parabola.nu/boards/5/topics/628
; I will attempt to remedy the situtation using pacman-key --refresh
.
I have abandonded Parabola since it feels to cumbersome. I will now install Guix, another supposedly free distribution.
pacman
keysAfter installing the bloated GUI variant of Parabola and fiddling with the mirrors via # vi /etc/pacman.d/mirrorlist
, the error: key "sixteen hex digits" could not be looked up remotely crept up again and again. See also https://wiki.parabola.nu/Installation_Guide#Verification_of_package_signatures
.
Alas, even pacman-key --refresh-keys && pacman -Syyu
did not aid.
In effect, disable all boolean flags in about:config
which match proton.
Cf. https://www.askvg.com/tip-restore-old-classic-theme-and-ui-in-firefox-89-and-later-versions/
, accessed 2021-06-04
% directory=~/some-dir date=2021-05-30 tar --sort=name --owner=root:0 --group=root:0 --mtime="UTC $date" -vcf "$directory".tar "$directory"
Cf. https://blog.jfrech.com/242/
% printf 'j=\\\n0;import J\n' > /tmp/j.hs && ghc -cpp /tmp/j.hs [1 of 1] Compiling Main ( /tmp/j.hs, /tmp/j.o ) /tmp/j.hs:1:5: error: parse error on input ‘import’ | 1 | j=\ | ^^^^^^
certbot
invocation% apt install --assume-yes certbot && certbot certonly --agree-tos --no-eff-email --email info@jfrech.com --standalone --preferred-challenges http --domains jfrech.com,factoids.jfrech.com
% sudo journalctl -f -u wakka.service
% echo 'eval "$(ssh-agent -s)" && ssh-add "$HOME/.ssh/github-ssh"' >> "$HOME/.shrc"
import random;''.join(hex(random.randint(1,15))[2:] for _ in range(8))
Even after installing Victor Mono through pkg install -y victor-mono-ttf
, the kerning is still off. I do neither know the cause nor how to fix it. Two links regarding fonts I found are https://forums.FreeBSD.org/threads/howto-nice-fonts.2021/post-11892
and https://docs.freebsd.org/en_US.ISO8859-1/books/handbook/x-fonts.html
# pkg install ghc hs-xmonad hs-xmobar # pkg install devel/pkgconf hs-cabal-install $ cabal install --lib xmonad xmonad-contrib % setxkbmap -layout de
I felt I had to leave Manjaro xfce4 (replaced by XMonad) behind. As I tried to formulate in Cccc, I feel a deep dissatisfaction with computing, the pseudo-non-proprietary nature and general associated stigma with it. Since FreeBSD 13.0-RELEASE has been recently released (https://download.freebsd.org/ftp/releases/amd64/amd64/ISO-IMAGES/13.0
states 2021-04-09 as a date), I decided to give it a try. In the following, I have documented my initial installation process, with a lot of details gathered from blog and BSD forum posts.
... booting into memstick ... ... FreeBSD greeter ... ... 1. Boot Multi user [Enter] ... [Enter] ... Welcome ... <Install> [Enter] ... Keymap Selection ... (select keymap) [Space] [Up] [Enter] ... Set Hostname ... twr.jfrech.local <OK> [Enter] ... Distribution Select ... <OK> [Enter] ... Network Installation ... <OK> [Enter] ... Network Configuration ... <OK> [Enter] <Yes> [Enter] <Yes> [Enter] <No> [Enter] [Tab] [Enter] ... Mirror Selection ... (select mirror) <OK> [Enter] ... Partitioning ... Auto (ZFS) [Enter] ... ZFS Configuration ... >>> Install <Select> [Enter] stripe <OK> [Enter] (select the correct disk to format) [Space] [Enter] [Left] [Enter] ... Fetching Distribution ... ... Archive Extraction ... ... FreeBSD Installer... Changing local password for root New Password:***** Retype new Password:***** ... Select local or UTC (Greenwich Mean Time) clock ... <Yes> [Enter] ... Time Zone Selector ... (select time zone) ... ... Time & Date ... <Skip> [Enter] <Skip> [Enter] ... System Configuration ... [ ] local_unbound [*] sshd [ ] moused [*] ntpdate [*] ntpd [*] powerd [*] dumpdev <OK> [Enter] ... System Hardening ... <OK> [Enter] ... Add User Accounts ... Username: j Full Name: j Uid (Leave empty for default): Login group [j]: Login group is j. Invite j into other groups? []: wheel video Login class [default]: Shell (sh csh tcsh nologin) [sh]: Home directory [/home/j]: Home directory permissions (Leave empty for default): Use password-based authentication [yes]: Use an empty password? (yes/no) [no]: Use a random password? (yes/no) [no]: Enter password: ***** Enter password again: ***** Lock out the account after creation? [no]: ... OK? (yes/no): yes adduser: INFO: Successfully added (j) to the user database. Add another user? (yes/no): no ... Final Configuration ... Exit <OK> [Enter] ... Manual Configuration ... <No> [Enter] ... Complete ... <Reboot> [Enter]
After reboot, one may configure the system:
$ su # pkg install xorg x11/nvidia-driver y # echo 'font8x16="/usr/share/vt/fonts/vgarom-thin-8x16.fnt"' >> /etc/rc.conf # echo 'kld_list="nvidia-modeset"' >> /etc/rc.conf # echo 'vbe_max_resolution="1080p"' >> /boot/loader.conf # echo 'kern.vty=vt' >> /boot/loader.conf # echo 'nvidia_load="YES"' >> /boot/loader.conf
Installing xfce4 is a breeze:
# pkg install xfce4 # startxfce4
I have not yet gotten XMonad to work ... Something regarding unfindable dynamic libraries.
# pkg install xterm # pkg install go # pkg install ghc hs-xmonad hs-xmobar hs-cabal-install # cabal update && cabal install xmonad xmobar # pkg install xterm ghc vim konsole hs-xmonad hs-xmobar
Multiple ways to set the virtual terminal's font:
$ vidcontrol -f /usr/share/vt/fonts/vgarom-thin-8x16.fnt $ vidfont ... VGAROM, 8x16 (thin) ... # echo 'font8x16="/usr/share/vt/fonts/vgarom-thin-8x16.fnt"' >> /etc/rc.conf
% wrzl timedatectl set-ntp trueRef.
https://github.com/jfrech/wrzl
.png
file using ImageMagick% convert -size 1920x1080 canvas:'#123456' mono.png
XMonad.Prompt.ShellPrompt
invocationRun: konsole -e sh -c 'ls && sleep 1'
Why does cc -xc -D'f(x,y,z)for(;*y;z++)x[z*=x[z]>0]=*y++;' =(echo 'main(){char X[99],Y[99];strcpy(X,"abcdefghijk");strcpy(Y,"wxyz");char*x=X,*y=Y;int z=4;f(x,y,z);puts(x);}')
not seem to work?
Ref. https://codegolf.stackexchange.com/a/223125/73111
Not verifying associativity is common, as it most of the time is a rather lengthy and uninsightful computation. Nevertheless, entrop-x has a short proof why not inverting the third intersection point in the origin (provided an elliptic curve in Weierstraß normal form, i. e. the origin is an inflection point) does lead to an algebraic structure worth studying on said elliptic curve: take any point A on the curve and look at B := A+A, that is the third point in the multiset defined by intersecting the tangent at A with the curve. Since no inversion is involved, symmetrically A+B = A holds. Assuming a group structure, one deduces A = A+B = A + (A+A), thus 0 = A-A = A+A = 2A and every element is of order <= 2.
Ref. entrop-x, 2017-12-16@07:41: https://crypto.stackexchange.com/questions/53974/when-adding-two-points-on-an-elliptic-curve-why-flip-over-the-x-axis#comment119429_53980
Most pograms weighted by use are probably prorpietary. Most software left is open-source yet definitely not free. A well-known open-source software exclusive to a certain Redmond-based monopoly's cornerstone is Notepad++. Yet the orthoganality thesis applies: there is a closed-source, proprietary piece of software for Ubuntu (an OS which is not free, plainly free-er): Primo (ref. http://www.ellipsa.eu/public/primo/primo.html
). It even comes with an EULA.
After hours of unfruitful XMonad configuring, I added XPC { font = "xft:" }
to my shellPrompt invocation (see https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Prompt-Shell.html
) and finally saw a prompt!
... , ((modMask, xK_p), shellPrompt def { font = "xft:" }) ...
Alt+Ctrl+F2 % wrzl vim /etc/default/grub ... GRUB_GFXMODE=1920x1080 ... GRUB_GFXPAYLOAD_LINUX=1920x1080 % wrzl update-grup && reboot % setfont /usr/share/kbd/consolefonts/ter-112n.pdf.gz
% curl -fsSL shakespeare.mit.edu/Poetry/sonnets.html | grep -o '^<DT><A HREF="[^"]*"' | grep -o '"[^"]*"$' | grep -o '[^"]*' | sed 's|^|shakespeare.mit.edu/Poetry/|' | xargs -L1 curl -fsSL > shakespeare.html
macOS Safari may add a white background to a tab's favicon to apparently enhance contrast in dark mode, though the exact methodology by which this is achieved is not known to me.
One may define a favicon mask (<link rel="mask-icon" href="..." color="#ac0101">
). This mask is displayed on the touch bar (for me it does not seem to be used for the pinned tab icon); yet only when exactly one tab is open and all favorite pages are shown. Open tabs are instead displayed as a page content preview.
for (var j = 0; j < 1024; ++j) document.getElementsByTagName('body')[0].innerHTML += '<div style="position: fixed; z-index: -8096; min-height: .1em; min-width: .1em; background-color: #aaaa88; left: ' + Math.random()*100 +'%; top: ' + Math.random()*100 + '%"></div>'
qpdf
% qpdf --empty --pages in.pdf 3 -- out.pdf
Lagrange
, a Geminispace browser, from the AUR% rm -rf "$HOME/src/lagrange" && mkdir -p "$HOME/src" && cd "$HOME/src" && git clone https://aur.archlinux.org/lagrange.git && cd lagrange && sudo pacman --noconfirm -S base-devel && makepkg --noconfirm -si
Die Last der \emph{Versager\textasteriskcentered{}innen}.
Ref. The Comprehensive LaTeX Symbol List.
validator.w3.org
's hottest tips<html lang="...">
.<script>...</script>
, never language=
or type=
.<article>
should have h2-h6
.<picture>
-<source>
requires a set sizes="100vw"
(as an example) attribute if it "has any image candidate string with a width descriptor" (ref. validator.w3.org
).% printf 'Testing GitHub ...\n' && eval "$(ssh-agent -s)" && ssh-add "$HOME/.ssh/github-ssh" && ssh -T git@github.com
I~became unrecog\-nizable.
display: block;
an <img>
tagElse it may lead no unwanted whitespace.
% sudo pacman --noconfirm -S zathura zathura-pdf-poppler
% eval "$(ssh-agent -s)" && ssh-add "$HOME/.ssh/github-ssh" && ssh -T git@github.com
% . =(curl -fsSL s.jfrech.com/github-ssh.sh)
% sudo vim /etc/ImageMagick-6/policy.xml +66
% curl -fsSL s.jfrech.com/setup-manjaro.sh | sh
No doubt it is a sin to make oneself dependent on proprietary Redmond software. However, what is one supposed to do if one's own state's institutions force one to use proprietary software? Is it really better to use Skype on an Ubuntu machine? I opted to keep my soul separated from "work" and thus begrudgingly installed Windows 10.
Yet I cannot and do not want to be able to stand PowerShell: Install "Debian" and "Windows Terminal" from the Microsoft Store (make sure to simply close the login request which pops up) and follow https://aka.ms/wslinstall
: Run PowerShell as administrator (possibly one may also be able to use the Windows Terminal for this purpose) and run dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
. Then restart. Launch "Debian" and setup the GNU+Linux system. After installation, the Windows Terminal should supply "Debian (Ctrl+Shift+4)" as an option in the downwards facing arrow in the tab bar.
To be able to edit the Windows Terminal's configuration file, I also installed Notepad++: https://notepad-plus-plus.org/downloads/v7.7.1/
. Of course, at first launch I had to immediately install an update. After having installed a program that can manipulate textual config files, I selected "Settings (Ctrl+Alt+,)" and edited line 11 to mention line 49's guid. This way, Windows Terminal always starts up with a Debian Bash prompt.
curl
invocations% # f: fail silently % # sS: silent mode yet still show errors % # L: follow links % curl -fsSL 'https://...' % # only usable in non-critical password usage scenarios % # u: set user name and password % curl -u username:password -fsSL 'https://...'
tar
invocations% ./generate-data.sh > data % [ -e data.tar ] && exit 0 % # generate a tar ball yet compress it yourself % # (`tar -z` may not imply `gzip --best`) % # v: verbosely % # c: create % # f: filename % tar -vcf data.tar data % gzip --best data % # if `data` should not be removed % gzip --best --keep data
% # v: verbosely % # x: extract % # f: filename % tar -vxf data.tar % tar -vxf data.tar.gz
vim
settingsI never quite remember where the default vim
settings are located. On my current Fedora 33 (x86-64) system, I commented out every single line in /etc/vimrc
to remove the odd bloaty choices of Fedora. I am very certain I will soon switch away from Fedora, I have to admit not to grok its appeal.
I wanted to screenshot a web page (i. e. generate a static .png
image) yet found my screen to be too pixel-sparse for the entire page to be viewable at a reasonable non-blur-pixelated scale. As such, I seeked and found a solution: Ctrl+Shift+I
to enter "developer tools", followed by Ctrl+Shift+M
to "[t]oggle device toolbar". In the top bar, one may choose rendering approach, ficticious device width and zoom (I chose Responsive, 1000 x 1000 @ 150%
) and is then able via a menu accessed by three vertical dots at the top-right of the web page window to "Capture [a] full size screenshot".
Ref. https://tools.ietf.org/search/rfc4648
https://www.w3.org/TR/SVG2/
https://developer.mozilla.org/en-US/docs/Web/SVG
https://developer.mozilla.org/en-US/docs/Web/SVG/Element
% find "$HOME/git" -mindepth 1 -maxdepth 1 -type d | xargs -L1 -I{} -- sh -c 'printf "\n\33[1m=== %s ===\33[m\n" "{}"; printf "\33[2m" ; git -C {} clean -xfdn ; printf "\33[m" ; git -C {} status -s ; git -C {} cherry -v'
On my *nix-y system, I found it at "$HOME/.config/BraveSoftware/Brave-Browser"
.
% git log --follow -p <file>
TODO I am unsure what --follow
and -p
exactly do.
Related: https://stackoverflow.com/a/9807682
ssh
daemon% systemctl status sshd || sudo systemctl start sshd && systemctl status sshd % ip addr | grep '^\s*inet\s\+'
On a new connection, the keys should theoretically be certified. Even if I unwisely often assume no man-in-the-middle attack to be happening (esp. on local networks), verification is easily performed by using `ssh-keygen -l`:
% ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub
explicit
.NOTE. I am clearly misunderstanding explicit
. This factoid is of little value.
If marked explicit
, implicit type conversions are forbidden. Note: When initializing classes with numeric values, an explicit constructor may be suboptimal as it also restricts the number type, i. e. I thought the following would not compile:
class A { private: float x; public: explicit A(float const x) : x{x} { ; } }; int main() { A a{0}; }
See also https://en.cppreference.com/w/cpp/language/explicit
Since the web stems from a time of naïf optimism, many once well-ment features can be weaponized. As such, due diligence is required when crafting HTML anchors:
<a href="..." target="_blank" rel="external noreferrer noopener">
I am still deliberating and researching the optimal rel
values. Some further ideas and links include:
<meta http-equiv="Content-Type" content="text/html; charset=utf8"/>
might be superfluous since one can also include this information in the HTTP POST header.https://stackoverflow.com/questions/40844731/custom-safari-bookmark-icon-and-color-on-touch-bar
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel
: rel="canonical? license? nofollow noopener noreferrer search?"
may prove usefulhttps://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
https://stackoverflow.com/questions/5110776/apple-touch-icon-for-websites/21144916#21144916
rel="external noreferrer noopener"
seems the most important to me.brew
's diagnostics% brew analytics off
See also docs.brew.sh/Analytics
.
Source: @article{en_2020-06-20_ct_homebrew-analytics,author={Crumbach,Ralf},title={Homebrew},journal={c't~; Magazin für Computer-Technik},date={2020-06-20},pages={8}}
I found bmon
to be a nifty tool. One only has to realize that scrolling down is most likely beneficial.
In OEIS sequence A074025, at first glance one might be surprised to read the entry 99999999999999999999
. Disappointingly, one soon realizes this "term [to be] a fake" (quote retrieved 2021-01-29).
Declaring is not not initializing; int x;
. Yet {}
-ing is zeroing: int x{}; int y{0}; int z(); int w(0);
. Furthermore, std::vector<int> xs(5);
forms a well-defined object, i. e. xs[3] == 0
.
When a std::vector
exceeds its capacity and needs to grow, it need not copy itself to a new memory block and then construct the pushed vector, but may do so in a potentially unintuitive order.
NOTE. An example may be of use.
NOTE. I ought to verify that the standard has no stance in this matter.