sh-ves: Bourne Shell Virtual Environment System
sh-ves: Bourne Shell Virtual Environment System
sh-ves is a collection of simple scripts for managing the values
of environment variables. It can be used to create independent
collections of variables, with their values, which are called
environments, and swap between them.
sh-ves is not a package manager, and does not directly interface
with a package manager. It simply allows swapping between environments,
so it is on the user to install the different versions of various packages
on their own, if they would like to use sh-ves for this.
Installation
To install, run
$ make install
which will copy the scripts into ~/.local/bin/ves_scripts,
create the sh-ves data directories, and install the ves(1)
man page to ~/.local/share/man/man1. Then add the following
line to your shell's rc or profile file,
. ~/.local/bin/ves_scripts/ves-init.sh
sh-ves operates by defining shell functions, so this file must be sourced
into each shell session that wants to use it. make uninstall
removes the scripts; make purge additionally removes all
data, including your saved environments.
fish
sh-ves also works in fish via a shim. If fish is detected,
make install copies ves.fish to
~/.config/fish/functions/ (which autoloads a
ves function — no rc file changes needed) and tab
completions to ~/.config/fish/completions/. The shim runs
each command through the real POSIX implementation in an
sh subshell, then replays any environment changes into the
fish session, so all commands behave identically. Activation state is
carried in exported SHVES_SAVED_* variables, so
activate/deactivate work across invocations.
Commands
sh-ves consists of a series of related scripts, which can be called
from a global wrapper function for convenience. All of these examples use
the global wrapper.
Create a new environment
A new environment can be created by using the command,
$ ves create <name>
The default environment will not override any environment variables
from the parent process. If you would like to override the PATH and LDPATH
variables, use the following,
$ ves create --override <name>
Be aware that this will truncate PATH and LDPATH to empty strings initially,
and so you will need to set these up yourself within the environment.
Activate an environment
To activate a created environment, use the command,
$ ves activate <name>
An environment of the specified name must exist, and no other ves environment
can be active already. ves environments do not support composition, and the
system will not allow a second environment to be activated on top of an
existing one.
Activating a ves environment will apply all of the stored environment
variables over top of the parent environment.
Deactivate an environment
To deactivate a ves environment, use the command,
$ ves deactivate
when within an active environment. This will restore the environment variables
to the state they were prior to activating the environment.
Switch between environments
As a convenience, the command,
$ ves switch <name>
will deactivate the current environment (if any) and activate the named
one in a single step.
Run a command inside an environment
To run a one-off command inside an environment without activating it,
$ ves run <name> <command...>
The environment is applied in a subshell, so the current shell is left
untouched and no deactivation is necessary.
Add a variable to the environment
To add a new environment variable to the environment, use the command
$ ves export [--env=<name>] <variable> <value>
If called from within an active ves environment, the --env
flag can be omitted, which will result in the export applying to the
active environment.
To remove a variable from an environment entirely,
$ ves unset [--env=<name>] <variable>
If the target environment is active, the live variable is restored to its
pre-activation value.
To see all variables stored in an environment,
$ ves show [<name>]
which defaults to the active environment when no name is given.
Manage PATH, LDPATH, etc.
A variety of important environment variables actually represent :-delimited
arrays, such as PATH and LDPATH. These are called "path-like" in sh-ves.
To facilitate managing these, sh-ves has some specific functionality
related to adding and removing elements from these variables.
To add an entry to a path-like variable,
$ ves var-add [--env=<name>] [--append] <variable> <value>
will prepend <value>: to the specified variable (or
append :<value> with the --append flag,
for fallback entries). If the variable is not yet stored in the
environment, it is seeded from the live shell value first, so prepending
to PATH never truncates it. To truncate PATH and friends deliberately,
create the environment with --override.
To remove an entry from a path-like variable,
$ ves var-rm [--env=<name>] <variable> <value>
will remove <value>: from a path-like variable, if it
is present.
ves will automatically expand <value> to an absolute
path using certain rules, for convenience, if it does not begin with a
/ or a ./. For example, values added to the
PATH will have,
$XDG_DATA_HOME/ves/bin/
prepended to them, and values added to LDPATH and LD_LIBRARY_PATH will
have,
$XDG_DATA_HOME/ves/lib/
prepended. It is advisable to install binaries and libraries that you
would like to participate in ves environments into independent
directories within these two locations.
You can also list the contents of a path-like variable using,
$ ves list [--index] <variable>
which will list the contents of the variable, each on its own line,
in order of precedence. The --index flag will cause the
command to list a numeric (starting at 0) index before each entry. Note
that ves list reads from the live shell, so it reflects the
current state of the variable, whether or not an environment is active.
List, copy, rename, and delete environments
To see all created environments,
$ ves envs
Environments can be duplicated and renamed with,
$ ves copy <src> <dst>
$ ves rename <old> <new>
and deleted with,
$ ves delete <name>
The currently active environment cannot be deleted or renamed; deactivate
it first.
Potential Use-cases
sh-ves can be used to manage different projects requiring specified
versions of compilers or libraries in a fairly transparent manner. For
example, consider a project that is targeted to GCC version 4 and
requires libexample version 6.12.
Using distribution/application specific means, the proper versions of
these packages are installed to ~/.local/share/ves/bin/gcc-4/
and ~/.local/share/ves/lib/libexample-6.12/ respectively.
A ves environment can be then set up for this project,
$ ves create example_project
$ ves activate example_project
$ ves var-add PATH gcc-4
$ ves var-add LDPATH libexample-6.12
Shell prompt integration
sh-ves has a built in helper that will automatically generate a string to
be included in your POSIX compliant shell's PS1 string (or where-ever else
you want it to go).
$ ves prompt [symbol]
([symbol] <name>)
This script doesn't do any color manipulation, so you can add color codes
prior to it within your prompt to configure it however you like. The
prompt string will only appear when an sh-ves environment is currently
active.
In fish, use the quoted command substitution form within your fish_prompt
function, so that the empty output when no environment is active does not
swallow adjacent arguments,
function fish_prompt
echo -n "$(ves prompt) "(prompt_pwd)' $ '
end
Testing
The test suite requires no external framework and can be run with,
$ make test
License
sh-ves is licensed under the GNU Affero General Public License,
version 3. See the LICENSE file for details.