3.0 KiB
Execute a command on the host
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.
The easy one
Install flatpak-spawn inside the container, this example is running on a
Fedora Distrobox:
~$ distrobox create --image fedora:35 --name fedora-distrobox
~$ distrobox enter --name fedora-distrobox
user@fedora-distrobox:~$ sudo dnf install -y flatpak-spawn
With flatpak-swpan we can easily execute commands on the host using:
user@fedora-distrobox:~$ flatpak-spawn --host bash -l
~$ # We're back on host!
The not so easy one
Alternatively you may don't have flatpak-spawn in the repository of your container,
or simply want an alternative.
We can use chroot to enter back into the host, and execute what we need!
Create an executable file with this content:
#!/bin/sh
result_command="sudo -E chroot --userspec=$(id -u):$(id -g) /run/host/ /usr/bin/env "
for i in $(printenv | grep "=" | grep -Ev ' |"' | grep -Ev "^(_)"); do
result_command="$result_command $i"
done
exec ${result_command} sh -c " cd ${PWD} && $@"
in ~/.local/bin/host-exec and make it executable with chmod +x ~/.local/bin/host-exec
Now we can simply use this to exec stuff back on the host:
user@fedora-distrobox:~$ host-exec bash -l
~$ # We're back on host!
Integrate host with container seamlessly
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
if command -v flatpak-spawn >/dev/null 2>&1; then
flatpak-spawn --host "${@}"
elif command -v host-exec >/dev/null 2>&1; then
host-exec "$@"
else
exit 127
fi
}
if [ -n "${ZSH_VERSION-}" ]; then
command_not_found_handler() {
command_not_found_handle "$@"
}
fi
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.