TIL

While it's pretty obvious that each OS has a way to determine which app is going to open a given file, I've never bothered to learn where this info is stored. Thanks to HackerNews I've stumbled upon xdgctl, which has great pointers on how the system works along with some good resources.

On completely unrelated news, I'm now stowing .config/mimeapps.list :)

Sources:

In systemd v259 you can run commands that need privileges as your current user instead of as root.

With run0 --empower, you'll get a session as your current user in which you can do anything that root would be able to do, without actually being root.

And of course this is done via linux's capabilities, in particular:

       CAP_DAC_READ_SEARCH
              •  Bypass file read permission checks and directory read
                 and execute permission checks;
              •  invoke open_by_handle_at(2);
              •  use the linkat(2) AT_EMPTY_PATH flag to create a link to
                 a file referred to by a file descriptor.

Source:

I love fail2ban but I don't want to test my failregex on the live server. It turns out this is not necessary because:

  1. there's a native fail2ban-regex tool that we can use to test both configurations and log files:
$ fail2ban-regex -v path/to/mock/log/file.log path/to/my/fail2ban/app.conf

This will print matches and what not.

  1. fail2ban simply uses the Python's regex library, so we can go for example to regex101.com, select Python and play there, and only after confirming everything works there we can do a final check with 1..

Source:

Another command that I was missing from my previous OS, from xdg-open's man:

xdg-open opens a file or URL in the user's preferred application.

Lovely.

Source:

(Not a Go Lang TIL)

Quote from Wikipedia:

"go fever" (also "launch fever") is an informal term used to refer to the overall attitude of being in a rush or hurry to get a project or task done while overlooking potential problems or mistakes.

TIL most of my career has been done under go fever. Admittedly, the projects I've worked on were never life-critical and, thankfully most software engineering issues can be fixed with another git push.

Source:

Add Defaults insults to /etc/sudoers (via sudo visudo):

$ sudo ls
[sudo] password for zntfdr:
Are you on drugs?
[sudo] password for zntfdr:
Where did you learn to type?
[sudo] password for zntfdr:
sudo: 3 incorrect password attempts

That's funny.

Sources:

Definition stolen from The Cathedral and the Bazaar:

Sociologists years ago discovered that the averaged opinion of a mass of equally expert (or equally ignorant) observers is quite a bit more reliable a predictor than the opinion of a single randomly-chosen one of the observers.

This is exactly why I rather brainstorm with an AI than a colleague: it’s as if I were talking to ten thousands experts with infinite winsdom and experience vs. talking to a single busy person.

One of the excuses I hear from engineers against introducing a formatter in a repository is that doing so will destroy the git blame history on files. Turns out git has something for this: by default git looks for a file in the repository root called .git-blame-ignore-revs which contains the hashes of commits to ignore, all changes made by these commits will not show up in git history.

Problem solved.

git

Quoting skitter:

Wow, Collect2 sounds kinda hacky based on the linked documentation:

  • There is user code that needs to run before main. With C/C++ allowing separate compilation, the compiler invocation that creates the entrypoint doesn't know about all of these static constructors.
  • Therefore collect2 pretends to be ld; when invoked, it tries to call the real ld and examines its output
  • It creates a c file with a table containing any constructor symbols it finds, then compiles that
  • Finally it links the program again, together with the new object file

Another commenter says that the documentation lies, but the source code [4] doesn't.

Sources:

I knew about xclip and xsel, however these are a bit annoying as they need various flags, to say whether we're copying or pasting, which I conveniently forget every time I need to use them.

Thanks to pay-respects I discovered this other tool combo which is exactly what I needed and should be much easier to remember (no extra flags necessary!), fingers crossed!

tiny-dfr is a tiny Linux daemon used to create a dynamic function row in dynamic keyboards, I think this is used mainly for devices with touchbar, and it's what I have to run when my os wakes up to a blank touchbar (alternatively: sudo systemctl start tiny-dfr.service).

I was getting the following error while setting up a new machine using an existing ssh key:

sign_and_send_pubkey: signing failed for ED25519 "/home/zntfdr/.ssh/id_ed25519" from agent: agent refused operation

The fact that the agent "refused operation" immediately told me that this was not a failure to my end in copying the ssh key but something else, it turns out that ssh requires certain file permissions to operate, fixed by running

chmod 700 ~/.ssh
chmod 600 ~/.ssh/*

I needed to ignore new files without adding them to .gitignore.

I'd normally do git update-index --assume-unchanged <file-paths>, however that doesn't work for files that have not be checked-in in the repository before.

In such cases we can use the file in .git/info/exclude, which behaves exactly like .gitignore but is completely local.

Sources:

git

⁠/dev/zero is a special file containing a sequence of zero bytes that can be used as a placeholder or dummy value in various scenarios where zeros are required.

...just don't call cat on it as the stream is infinite.

I have auto-format on save enabled for some languages, for example go:

    vim.api.nvim_create_autocmd('BufWritePost', {
      group = 'Format',
      pattern = '*.go',
      callback = function()
        vim.lsp.buf.format()
      end
    })

For everything else, we can use the = nvim motion for indenting a file!

Sources:

⌘+↹ is used to jump between applications (I never use it, skhd FTW), `⌘+`` is used to jump between windows of the same application, nice.

unattended-upgrade (source) is a small utility that used to come in with Debian and enabled by default (no longer true from Debian 12/Bookwarm), its purpose is to automatically update (security and non) packages automatically without human intervention.

I only noticed it was running on my machine after noticing that the usual sudo apt update/upgrade updated a very small number of packages, this is very cool!

I also really appreciate the man page description section of this script:

DESCRIPTION
       This program can download and install security upgrades automatically and unattended, taking care to only install packages from the configured APT source, and checking for dpkg prompts about configuration file changes. All operations are logged to /var/log/unattended-upgrades/unattended-upgrades.log and the package manager (dpkg) output is logged
       to /var/log/unattended-upgrades/unattended-upgrades-dpkg.log

       This script is the backend for the APT::Periodic::Unattended-Upgrade option and designed to be run periodically by APT's systemd service (apt-daily-upgrade.service) or from cron (e.g. via /etc/cron.daily/apt).

It tells you concisely:

  • what it does
  • where it logs
    • why so many unix tools don't tells you this? It's so important
  • how it's meant to be used
    • they don't spell out systemctl status apt-daily-upgrade.service or sudo crontab -e but they give more than enough details on how to find out about it

Props to the authors, I wish more man pages where this complete.

Update: for OSes with dnf, there's dnf-automatic dnf5 plugin, which has multiple configurations (like download-only, install security-only updates, do no reboot...)

All the following matches are symbolic links to /usr/bin/vim:

$ find -L / -samefile /usr/bin/vim
/usr/bin/rview
/usr/bin/vim
/usr/bin/vi
/usr/bin/vimdiff
/usr/bin/ex
/usr/bin/rvim
/usr/bin/view

Each starts vim in a different manner/mode, for example ex will launch vim in Ex mode.

The way this is handled is by checking the value of argv[0] passed in int main(int argc, char **argv), clever!

It's common to update a shell environment variable by replacing it entirely:

$ SOME_VAR=hi
$ echo $SOME_VAR
hi
$ SOME_VAR=hi2
$ echo $SOME_VAR
hi2

However zshoffers vared, which uses zle to prompt us update the current value without having to read/write it ourselves:

$ SOME_VAR=hi
$ echo $SOME_VAR
hi
~/.dotfiles main $ vared SOME_VAR
hi▋                                 #<-- this is the original prompt with our cursor
hi2▋                                #<-- let's type "2" and hit return
~/.dotfiles main $ echo $SOME_VAR
hi2

handy!

Source:

zsh

Learned while listening to Rustacean Station, from the source link below:

Inlining: Performed during the graph generation phase. The inlining heuristic is very simple: basically, if the function being called is known, and it is safe to inline, the function will be inlined. Large functions (>600 source characters including whitespace or 196 AST nodes) will not be inlined. Cumulatively, a total of 196 AST nodes can be inlined in a single function.

This means that adding or removing comments can make a difference to inlining and, therefore, the performance of an application.

Source:

zsh

I've been postponing doing the this tutorial for nearly two years, some of these "TIL" are not really TILs, but more of a "I saw once, thought it was cool, and the promptly forgot".

  • in normal mode
    • press A to move to insert mode at the end of the current line (I've been doing $i all this time..)
    • press U to undo all latest changes on the current line.
      Note that this only undoes the changes for this line from the last insert mode, it doesn't restore the line as it was when opening the file
    • press P to paste the text before the cursor (this works both when pasting words or entire lines), I only used p so far!
    • THE CHANGE OPERATOR
    • <C-o> and <C-i> to jump around the cursor position history, I never remember this one and press <C-0> instead
    • The substitute command, I always used :%s/old/new/g, as that's what I wanted most of the time, but it's actually :<some-operator>s/old/new/ meaning I can do:
      • :s/old/new/ for editing only the current line
      • :1,3s/old/new/ to only edit lines 1 to 3
      • :100s/old/new/ to only edit line 100
      • :'<,'>s/old/new/ to only edit whatever I have selected
    • REPLACE MODE
  • when reading nvim documentation (or man pages via MANPAGER=nvim +Man!) (I keep forgetting these):
    • press K to jump to the hovered word documentation (or man page)
    • press <Enter> on a link to open the linked help section
  • the retrieve (:r) command :r FILENAME or :r !<command> to paste the contents wherever the cursor currently is.
Older