About me: My name is Solène Rapenne, pronouns she/her. I like learning and sharing knowledge. Hobbies: '(BSD OpenBSD Qubes OS Lisp cmdline gaming security QubesOS internet-stuff). I love percent and lambda characters. OpenBSD developer solene@. No AI is involved in this blog.

Contact me: solene at dataswamp dot org or @solene@bsd.network (mastodon).

I'm a freelance OpenBSD, FreeBSD, Linux and Qubes OS consultant, this includes DevOps, DevSecOps, technical writing or documentation work. If you enjoy this blog, you can sponsor my open source work financially so I can write this blog and contribute to Free Software as my daily job.

Implement a «Command not found» handler in OpenBSD

Written by Solène, on 09 March 2021.
Tags: #openbsd

Comments on Fediverse/Mastodon

1. Introduction §

On many Linux systems, there is a special program run by the shell (configured by default) that will tell you which package provide a command you tried to run but is not available in $PATH. Let's do the same for OpenBSD!

2. Prerequisites §

We will need to install the package pkglocate to find binaries.

# pkg_add pkglocate

We will also need a file /usr/local/bin/command-not-found executable with this content:

#!/bin/sh

CMD="$1"

RESULT=$(pkglocate */bin/${CMD} */sbin/${CMD} | cut -d ':' -f 1)

if [ -n "$RESULT" ]
then
    echo "The following package(s) contain program ${CMD}"
    for result in $RESULT
    do
        echo "    - $result"
    done
else
    echo "pkglocate didn't find a package providing program ${CMD}"
fi

3. Configuration §

Now, we need to configure the shell to run this command when it detects an error corresponding to an unknown command. This is possible with bash, zsh or fish at least.

3.1. Bash configuration §

Let's go with bash, add this to your bash configuration file

command_not_found_handle()
{
    /usr/local/bin/command-not-found "$1"
}

3.2. Fish configuration §

function fish_command_not_found
    /usr/local/bin/command-not-found $argv[1]
end

3.3. ZSH configuration §

function command_not_found_handler()
{
    /usr/local/bin/command-not-found "$1"
}

4. Trying it §

Now that you configured your shell correctly, if you run a command in your shell that isn't available in your PATH, you may have either a success with a list of packages giving the command or that the command can't be found in any package (unlucky).

This is a successful output that found the program we were trying to run.

$ pup
The following package(s) contain program pup
    - pup-0.4.0p0

This is a result showing that no package found a program named "steam".

$ steam
pkglocate didn't find a package providing program steam