It may be needed to execute commands back on the host. Be it the filemanager, an archive manager, a container manager and so on.
Here are a couple of solutions.
distrobox offers the distrobox-host-exec
helper, that can be used exactly for this.
See distrobox-host-exec.
user@fedora-distrobox:~$ which podman
/usr/bin/which: no podman in [...]
user@fedora-distrobox:~$ distrobox-host-exec podman version # <-- this is executed on host.
Client:
Version: 3.4.2
API Version: 3.4.2
Go Version: go1.16.6
Built: Thu Jan 1 01:00:00 1970
OS/Arch: linux/amd64
Server:
Version: 3.4.2
API Version: 3.4.2
Go Version: go1.16.6
Built: Thu Jan 1 01:00:00 1970
OS/Arch: linux/amd64
Another way to execute commands on the host, is to create executables symlinking distrobox-host-exec
:
user@fedora-distrobox:~$ ln -s /usr/bin/distrobox-host-exec /usr/local/bin/podman
user@fedora-distrobox:~$ ls -l /usr/local/bin/podman
lrwxrwxrwx. 1 root root 51 Jul 11 19:26 /usr/local/bin/podman -> /usr/bin/distrobox-host-exec
user@fedora-distrobox:~$ podman version # <-- this is executed on host. Equivalent to "distrobox-host-exec podman version"
Client:
Version: 3.4.2
API Version: 3.4.2
Go Version: go1.16.6
Built: Thu Jan 1 01:00:00 1970
OS/Arch: linux/amd64
Server:
Version: 3.4.2
API Version: 3.4.2
Go Version: go1.16.6
Built: Thu Jan 1 01:00:00 1970
OS/Arch: linux/amd64
Another cool trick we can pull, is to use the handy command_not_found_handle
function
to try and execute missing commands in the container on the host.
Place this in your ~/.profile
:
command_not_found_handle() {
# don't run if not in a container
if [ ! -e /run/.containerenv ] && [ ! -e /.dockerenv ]; then
exit 127
fi
distrobox-host-exec "${@}"
}
if [ -n "${ZSH_VERSION-}" ]; then
command_not_found_handler() {
command_not_found_handle "$@"
}
fi
And then, run source ~/.profile
to reload .profile
in the current session.
Place this snippet in a new fish function file (~/.config/fish/functions/fish_command_not_found.fish
):
function fish_command_not_found
# "In a container" check
if test -e /run/.containerenv -o -e /.dockerenv
distrobox-host-exec $argv
else
__fish_default_command_not_found_handler $argv
end
end
And restart your terminal. Now when a command does not exist on your container, it will be automatically executed back on the host:
user@fedora-distrobox:~$ which podman
/usr/bin/which: no podman in [...]
user@fedora-distrobox:~$ podman version # <-- this is automatically executed on host.
Client:
Version: 3.4.2
API Version: 3.4.2
Go Version: go1.16.6
Built: Thu Jan 1 01:00:00 1970
OS/Arch: linux/amd64
Server:
Version: 3.4.2
API Version: 3.4.2
Go Version: go1.16.6
Built: Thu Jan 1 01:00:00 1970
OS/Arch: linux/amd64
This is also useful to open code
, xdg-open
, or flatpak
from within the container
seamlessly.