Have you ever struggled to install obscure software? You try your distro’s software repositories first, falling back to community repositories. Sometimes you fail, and it’s not on the Snap Store or Flathub either, so you manually download it from GitHub as a last resort. There is a better way, and I’ll show you how.
Finding, downloading, and installing software manually is a drag. There are several tools at our disposal, each with its own strengths, but the Universal Binary Installer (UBI) solves that problem better than most. I will cover what it is, what problem it solves, how it works, and how to use it.
What is UBI?
In a nutshell, UBI is a small Rust program that installs binaries from GitHub or GitLab. Software developers don’t just publish their code on these platforms; they often build and publish it there too. UBI goes directly to the source while automating the boring parts for you.
Understanding GitHub releases
A GitHub release is a set of project artifacts (build outputs, like tarballs) published to a project-specific web page on GitHub. For example, the lazydocker repository publishes binaries you can download and execute. The GitHub releases page for a project may have many links, organized by version.
The filenames typically contain many details about the build artifact. For example, you can see from the previous image that lazydocker’s filenames look something like this:
lazydocker_0.24.2_Linux_x86_64.tar.gz
GitHub does not enforce a standard naming convention, so names may take any form. The format that lazydocker uses is common, however, and we can generally expect them to include the project name, version, platform, and sometimes libc information (e.g., glibc or musl).
Libc is the C standard library. It’s a collection of shared objects (e.g., libc.so.6 or libresolve.so.2) on most Linux systems that provides programming utilities for applications. They’re crucial for applications to function.
The problem UBI solves
For a one-off trial, manually downloading software is fine. But for long-term usage, it becomes a chore—you must visit the page, download and unpack the archive, move the binary, set the execute bit, and then change its ownership. You may write a Bash script to simplify that process, but it’s too much friction just to install one application.
UBI makes the installation of any software from GitHub or GitLab convenient. Now small and independent projects are more accessible than ever. It means you can step outside your distro’s ecosystem and access bleeding-edge software from one of the largest repositories on Earth.
Related
3 useful Linux apps worth trying this weekend (December 5 – 7)
Want to monitor a device’s resources remotely without SSH? Take a look at the first one.
How UBI finds the right binary
GitHub releases contain build artifacts for various platforms, versions, and supporting documents. UBI must choose the most suitable one for your system.
UBI uses a process of elimination to exclude irrelevant archives, which looks like this:
- Filter out unknown extensions (e.g., .foo, .bar).
-
If there’s one archive left, use it; otherwise, filter out irrelevant…
- Operating systems.
- CPU architectures
- Libc builds (e.g., musl or glibc).
- Filter out 64/32 bit
One archive should remain; otherwise, you can explicitly specify a match using the –matching flag.
Once it has selected the archive, UBI must choose the correct executable from it, because often these builds come with additional files.
The process is simple; it will select a file whose name either…
- Matches the project.
- Starts with the project name: e.g., foo-v1.2.3, foo-linux-amd64.
In short, UBI filters the list of archives by extension and platform information; then, it extracts (and renames) a binary that matches the project name.
Installing UBI
Installing UBI is straightforward, although some would groan about curl-bashing. I’ve improved the installation script so that it includes the necessary “BIN_DIR” in your PATH variable. That is where your installed binaries live, and you’re free to change it, but if you do, you must use the –in flag when installing applications. I recommend creating an alias for that.
BIN_DIR=”$HOME/bin”
mkdir -p “$BIN_DIR” \
&& curl –silent –location \
https://raw.githubusercontent.com/houseabsolute/ubi/master/bootstrap/bootstrap-ubi.sh \
| TARGET=”$BIN_DIR” sh \
&& { \
if [[ “:$PATH:” != *”:$BIN_DIR:”* ]]; then \
for rc in ~/.zshrc ~/.bashrc; do \
if [ -f “$rc” ]; then \
echo “export PATH=\”$BIN_DIR:\$PATH\”” >> “$rc”; \
echo “Added $BIN_DIR to PATH in $rc”; \
fi; \
done; \
fi; \
}
You may need to reload your shell if it added the path to your config: source ~/.bashrc for Bash or source ~/.zshrc for Zsh.
Using UBI
To install software from a GitHub repository, all you need are the owner and repository names. A GitHub URL looks like this:
https://github.com/houseabsolute/ubi
The path segments “houseabsolute” and “ubi” are the owner and repository names, respectively.
Just as an example, to install UBI (with UBI), execute:
ubi –project houseabsolute/ubi
That’s it. In your shell config, you can create an alias or function to make things easier:
add() {
case “$1” in
ubi) ubi –project houseabsolute/ubi ;;
*) echo “Unhandled project: ‘$1′” ;;
esac
}
“install” is a command on most systems, so I called the function “add” instead.
Handle edge cases
Sometimes the match algorithm doesn’t resolve to a single archive, because the publishers defined some additional (unhandled) elements in their names. You have a few options for managing these edge cases.
Given a release that has additional “foo” and “bar” elements in its name:
ubi-Linux-musl-foo-x86_64.tar.gz
ubi-Linux-musl-bar-x86_64.tar.gz
The “–matching” flag allows you to distinguish between them:
ubi –project houseabsolute/ubi –matching foo
Or you can use Regex:
ubi –project houseabsolute/ubi –matching-regex ‘.+-foo-.+’
“–matching” applies the filter after the default matching algorithm, and “–matching-regex” before.
To install a specific version, specify a tag:
ubi –project houseabsolute/ubi –tag v0.8.2
The image shows how to determine tag names for specific releases.
Sometimes the archive doesn’t contain a suitably named executable (e.g., the project name). In that case, use the “–exe” flag to specify the target:
ubi –project houseabsolute/ubi –exe ubi
Lastly, you can specify the output directory for the binary with the “–in” flag:
ubi –project houseabsolute/ubi –in ~/.local/bin
Related
7 Criminally-Underrated Linux Apps I Can’t Live Without
Seven free apps that are worth paying for.
UBI is a simple program that plugs a long-standing gap in the Linux software ecosystem, where niche or independent packages were difficult to get automatically. UBI fills that void, and it won’t make a fuss. It doesn’t pull in thousands of dependencies or require SELinux sandboxing. There’s no caching or complex packaging formats. It leverages a channel that most developers already use, giving you access to bleeding-edge projects.
I also use Distrobox to install hard-to-get software on any system. With Distrobox, UBI, and the official and community Linux repositories: it’s difficult to find applications I can’t use.
Related
This open-source Linux app got me to ditch the git command
It’s probably the best TUI I’ve used, and it looks great too.
