Last active
February 9, 2023 14:52
-
-
Save StefanFabian/cfc3408f4fc1bb302438a10064c21d9a to your computer and use it in GitHub Desktop.
MultiEnv: A small bash tool to handle multiple (possibly) clashing bash environments, e.g., different ROS workspaces
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ___ ___ _ _ _ _____ _ ____ __ _ __ __ | |
# | \/ | | | | | | | |_ _| | | | __| | \ | | \ \ / / | |
# | |\ /| | | |_| | | |__ | | | | | |__ | \ | | \ \ / / | |
# |_| \/ |_| |_____| |____| |_| |_| | __| | |\ \| | \ \/ / | |
# | |__ | | \ | \ / | |
# v1.0 by Stefan Fabian |____| |_| \__| \/ | |
# | |
# This script installs multienv, a small bash tool that allows you to easily switch between environments. | |
# For available commands run 'multienv help' after installation. | |
# Tab-completion is also supported! | |
# | |
# For example, let's say you have an environment using a catkin workspace overlaying the | |
# ROS (Robot Operation System) software stack. | |
# You would create an env named my_workspace: | |
# multienv create my_workspace | |
# | |
# This would open up an editor with a shebang line already filled in, you would modify it to contain: | |
# #!/bin/bash | |
# source /home/user/workspace_path/devel/setup.bash | |
# | |
# Save the file and exit. Now, you've created an environment. | |
# To switch to it, run: | |
# multienv switch my_workspace | |
# | |
# This will start a new shell session and source the script you created above. | |
# You do some work in that environment and after you're done, you want to switch the environment off again. | |
# For that, there's the special 'none' environment. | |
# multienv switch none | |
# | |
# This will start a new shell session and not source anything. | |
# Alternatively, you could also switch to a different environment (after you created more than one). | |
# A new terminal will always start with the session that was last switched to. | |
# To switch only your currently active terminal use the --this option. | |
# | |
# ========= | |
# CHANGELOG | |
# ========= | |
# v1.0: | |
# - Added reload command | |
# - Fixed env switch changing directory to the user's home directory | |
# | |
MULTIENV_INSTALL_DIR=~/.multienv | |
NC='\033[0m' | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
BROWN='\033[0;33m' | |
BLUE='\033[0;34m' | |
function info() { | |
echo -e "${BLUE}${1}${NC}" | |
} | |
function warn() { | |
echo -e "${BROWN}${1}${NC}" | |
} | |
function success() { | |
echo -e "${GREEN}${1}${NC}" | |
} | |
function error() { | |
echo -e "${RED}${1}${NC}" | |
} | |
if [[ -d $MULTIENV_INSTALL_DIR ]]; then | |
echo "It looks like multienv is already installed!" | |
read -p "Proceed anyway? (Y/n): " MULTIENV_INSTALL_PROCEED | |
if [[ $MULTIENV_INSTALL_PROCEED != "Y" && $MULTIENV_INSTALL_PROCEED != "y" ]]; then | |
exit 0 | |
fi | |
fi | |
echo -e "\e[31m ___ ___ \e[33m _ _ \e[32m _ \e[36m _____ \e[34m _ \e[0m ____ __ _ __ __" | |
echo -e "\e[31m| \/ | \e[33m| | | | \e[32m| | \e[36m|_ _| \e[34m| | \e[0m| __| | \ | | \ \ / /" | |
echo -e "\e[31m| |\ /| | \e[33m| |_| | \e[32m| |__ \e[36m | | \e[34m| | \e[0m| |__ | \ | | \ \ / / " | |
echo -e "\e[31m|_| \/ |_| \e[33m|_____| \e[32m|____|\e[36m |_| \e[34m|_| \e[0m| __| | |\ \| | \ \/ / " | |
echo " | |__ | | \ | \ / " | |
echo "v1.0 by Stefan Fabian |____| |_| \__| \/ " | |
echo | |
info "> Creating directory" | |
mkdir -p $MULTIENV_INSTALL_DIR/envs | |
info "> Configuration" | |
echo "Would you like to enable write protection?" | |
echo "Write protection requires sudo privileges to create, edit, delete environments as the relevant files will be write protected from normal users to prevent malicious modification." | |
read -p "Enable? (Y/n): " MULTIENV_INSTALL_WRITE_PROTECTION | |
if [[ $MULTIENV_INSTALL_WRITE_PROTECTION == "y" || $MULTIENV_INSTALL_WRITE_PROTECTION == "Y" ]]; then | |
success "Write protection enabled!" | |
else | |
echo -e "Write protection ${RED}not${NC} enabled." | |
fi | |
info "> Unzipping content" | |
if [ -f $MULTIENV_INSTALL_DIR/multienv.sh ] && [ ! -w $MULTIENV_INSTALL_DIR/multienv.sh ]; then | |
warn "Looks like you're reinstalling and write protection is enabled." | |
warn "Removing write protection (temporarily unless not enabled this time) for update." | |
sudo chattr -i $MULTIENV_INSTALL_DIR/multienv.sh | |
fi | |
echo "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" | base64 -d | gzip -d > $MULTIENV_INSTALL_DIR/multienv.sh | |
if [ $? -ne 0 ]; then | |
error "An error occured while unzipping!" | |
exit 1 | |
else | |
success "Unzipped $MULTIENV_INSTALL_DIR/multienv.sh" | |
fi | |
if [[ $MULTIENV_INSTALL_WRITE_PROTECTION == "y" || $MULTIENV_INSTALL_WRITE_PROTECTION == "Y" ]]; then | |
sudo chattr +i $MULTIENV_INSTALL_DIR/multienv.sh | |
sudo chmod 555 $MULTIENV_INSTALL_DIR/envs | |
fi | |
info "> Append to .bashrc" | |
MULTIENV_SOURCE_COMMAND="source $MULTIENV_INSTALL_DIR/multienv.sh" | |
if [ ! -w ~/.bashrc ]; then | |
error "Your .bashrc seems to be write protected. Good for security!" | |
echo "However, that means you will have to add the following yourself:" | |
echo "source $MULTIENV_INSTALL_DIR/multienv.sh" | |
exit 0 | |
fi | |
# Remove old source if exists | |
sed -i -z "s/$(echo -ne $MULTIENV_SOURCE_COMMAND | sed 's,/,\\/,g' | tr '\n' '^' | sed 's/\^/\\n/g')//g" ~/.bashrc | |
echo $MULTIENV_SOURCE_COMMAND >> ~/.bashrc | |
success "All done." |
Update v1.0
- Added reload command that will reload the active environment and reset the environment.
- Fixed environment switch or reload resulting in a change of the current working directory back to the users home directory
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
MultiEnv is a small bash tool that enables the separation of different console environments with minimal footprint.
You can create environments that consist of a few lines of bash that are sourced whenever the environment is loaded.
Switching environments is persistent between terminal sessions which means if you switch the environment and open a new terminal, the new terminal will also use the environment you switched to.
Use cases for this tool include the separation of different ROS or ROS 1 and ROS 2 workspaces.
Switching the environment will produce a clean bash where the other environment was never sourced. Bash history is preserved.
Changelog v0.9:
Added
--this
option formultienv switch ENV_NAME
to switch only active terminal.Fixed some security flaws that would have allowed to inject code to be run when multienv is sourced.