cnf 0.3.0

Find commands somewhere else
Documentation

CNF - A distribution agnostic "command not found"

This repository contains a "command not found" utility that aims to find commands not currently available in $PATH. It achieves this by querying various sources for the required command and offering to install them as necessary, currently including:

  • The system $PATH (see below for how this makes sense)
  • The current working directory (locally defined scripts)
  • dnf, the default package manager on Fedora and Red Hat Linux variants
  • cargo, the rust package manager
  • pacman, the default package manager on Arch Linux distributions
  • custom: Bring your own extensions/scripts - refer to the docs for additional information

cnf has integration with toolbx, too, meaning that it will query all the sources above on your host and in a user-configurable toolbx in parallel.

This process can be invoked by explicitly calling the cnf executable, or implicitly/automatically by hooking into your shell (currently supports bash and zsh). Refer to the output of cnf --hooks bash/zsh for further information.

Usage examples

The examples below assume you have already installed the necessary shell hooks, described below. If you haven't, you must prepend cnf to the relevant command lines.

cnf with toolbx

If you are a toolbx user, cnf can support you in transparently forwarding commands between your host and a chosen toolbx container. Here's an example of how cnf can replace toolbox run:

# Before
$ htop
htop: command not found
$ toolbox run htop
# After
$ htop

It also works the other way around. Assume you're currently inside your toolbx and want to execute a command on your host. Here's an example of how cnf can replace flatpak-spawn --host:

# Before
 $ podman run hello-world
podman: command not found
 $ flatpak-spawn --host podman run hello-world
# After
 $ podman run hello-world

Installation

If you want to automatically run cnf whenever a specific command isn't found, you must perform the following one-time setup:

# If you're using bash
$ cnf --hooks bash >> ~/.bashrc
# Likewise for zsh
$ cnf --hooks zsh >> ~/.zshrc

If you don't know which shell you're currently using, the output of the following command should tell you:

basename $(readlink -f /proc/$$/exe)

Now restart your shell or open a new shell tab/window and try it out!

Configuration

When you run this command for the first time, it will create a default configuration file in ~/.config/cnf/cnf.toml. The options should be self-explanatory.

CNF and sudo

When running commands with sudo, you will realize that the default "command not found" text is displayed. That is because sudo performs its own executable lookups, and if it can't find the command you were asking it to execute, it will print this error and exit. There are two ways to "fix" this:

The manual method

You directly call cnf with the command line that sudo couldn't find, like this:

$ sudo foobar
sudo: foobar: command not found
$ cnf !!

The !! will be expanded by your shell to the last command you executed, verbatim, including all of its arguments. This way you're forwarding the command to cnf directly. In other words: You're doing the shell hooks job, but manually.

The automatic method

Replacing your sudo executable happens at your own responsibility. Please be very careful with this, as of currently this program has undergone minimal testing.

Copy (or link) the utils/sudo from this repository to some location on your $PATH, like $HOME/.local/bin.

cp utils/sudo ~/.local/bin/
# Or link it like this:
# ln -s $PWD/utils/sudo ~/.local/bin/sudo

This wraps around sudo and forwards all commands unknown to sudo to cnf. All other commands are forwarded to your systems sudo under /usr/bin/sudo.