|0.2.0||Oct 11, 2023|
|0.1.0||Aug 31, 2023|
#80 in Configuration
EnvShim is a symlink shim to load executables with user-defined environment variables. Refer next section for more details on what this means.
Status: This project is active and a 1.0 release is planned. It currently has all the features I personally expect from it and is of beta quality. However, it will be in 0.x version for a while to identify any bugs or essentially needed features. Not a lot of features will be added, since that may slow down program and delay the loading of the final application.
EnvShim in detail
The problem: A big issue on a GNU/Linux desktop is that there are so many incompatible ways to
define environment variables. A cursory search indicates
/etc/environment and numerous other
locations. There is no reliable method to define all the variables in one place and have all the
applications pick them up. There are also surprising ways in which desktop managers like SDDM and
GDM process these variables. Some desktop environments like Gnome and KDE force a standard way of
defining users' environment variables. However, it's still an issue on window managers like sway or
The solution: EnvShim aims to provide a way for users to define their variables in a single
source of truth (
~/.config/envshim/script file) and ensure that the desired applications pick it
The way EnvShim solves this is by acting as a loader shim for the desired target applications. For
this, symlinks to the
envshim executable is with the same name as the target application is placed
in directory that has precedence over the actual target application in the $PATH variable. Consider
an example using the sway executable:
_# printenv PATH /usr/local/sbin:/usr/local/bin:/usr/bin _# which sway /usr/bin/sway _# which envshim /usr/local/bin/envshim _# ln -sr /usr/local/bin/envshim /usr/local/bin/sway _# rehash _# which sway /usr/local/bin/sway
In the above case,
/usr/local/bin has a higher precedence than
/usr/bin. Therefore, when we try
to execute sway,
envshim will be invoked via the symlink in
/usr/local/bin instead of
/usr/bin/sway. Envshim then takes care of initializing the variables and then invoking the target
User settings: The second requirement for this to work is a file where the variables are
declared. This has to created by the user in their home directory under
$XDG_CONFIG_HOME is undefined, the default location is
script file is a shell script written for a shell (like
bash) of user's choice. At
the time of shim loading,
envshim invokes that shell as a subprocess and feeds the content of the
script to it. Envshim then reads the result of the script execution and uses it to define the
environment for the target application. Envshim then
execs into the target application, replacing
itself with the target application in the process.
Clone this repository and cd into it. Then issue the normal
cargo command to build it. Copy the
executable to the desired location afterwards.
git clone https://git.sr.ht/~gokuldas/envshim cd envshim cargo build --release sudo cp target/release/envshim /usr/local/bin
There are two steps in the configuration process:
1. Script file: The user has to create a script file at
doesn't need an executable permission. The first line is a shebang line indicating the shell to
use and configured to accept input from stdin. The following are some options:
Fill the script file to print the necessary variables in a
VAR=value format, one variable per
line. This can be done using
echo, for example. If it's desired to print out all the environment
variables at once,
printenv command does the job. Just remember to
export the variables before
printenv. For example:
export PATH=$HOME/.local/bin:$PATH printenv echo 'ENVSHIM_MARKER=envshim'
A sample of this file is provided as
assets/script in this repo.
2. Create shims: Shims are symlinks with the same name as the target and pointing to
executable. The important matter here is to ensure that the shims come first in $PATH before the
target executable. For example, if
PATH=/usr/local/bin:/usr/bin and the target application is
/usr/local/bin/sway is reasonable choice for the shim. Another matter to
note is that PATH variable mentioned here is what you get before shim loading. Don't depend on paths
defined in the script file. Have a look at the example given in 'EnvShim in detail' section.
Which applications should be chosen for shim loading? There are two guidelines that can help decide.
- Any application for which you want to ensure the correct variables
- Any application that is the parent process of most other applications
Shim loading adds a delay time to the loading of the target application, since a shell has to be run before it. The second guideline helps to reduce such delays by doing shim loading fewer times and then passing on the result to as many other processes as possible. Here are some possible candidate for shim loading:
- Shells (like bash or zsh)
- Window managers (like sway or awesome)
Envshim is designed to run the target application in any of the cases where the target is available. This means that the target will run even if the shell or the script fails or is missing. However, the environment variables that the target receives may not be what you expect. It's designed like this to avoid making the target application inaccessible in case of any other error. You wouldn't want your shell or window manager to be inaccessible because of a missing or misconfigured script.
If you suspect such a fail-safe shim load, you should try running the application from a command shell. EnvShell prints error messages on stderr if it encounters any problem.
Suggestions and contributions are welcome through the mailing list. Refer to the Contributor Guidelines and Project Policies page of my free software index for details on how to contribute. Meanwhile, the following additional guidelines apply:
- Format your code with
- The text width for markdown documents is 100
- The patches must be signed-off (
git commit -s)
- Set up the cloned local repository with the following configuration:
git config format.to "~email@example.com" git config format.subjectPrefix "PATCH EnvShim" git config format.coverLetter auto git config format.useAutoBase true git config format.signOff true
envshim: Symlink shim to load executables with user-defined environment variables
Copyright (C) 2023 Gokul Das B
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.