Skip to main content

How to use a repository for importing your bash scripts and shortcuts

ยท 4 min read
Carlos Angulo Mascarell

In this post, I will explain how to load custom variables by reading a JSON file, this will be done every time we open a Terminal. I will also improve the shortcuts we create in the previous posts.

Template ready to use!

The cangulo-templates/linux-terminal-profile repository contains a ready-to-use template based on this article.

Requirements

  • Linux (I'm using Elementary OS, a Ubuntu-based distro, try it!)
  • VS Code. If you don't want to use it, change all the code commands in the bash code for your text editor. Alternatives: gedit or gnome-text-editor.
  • fzf command-line fuzzy finder

Notes

  • Remember to add execution permissions to the scripts through chmod +x
  • Profile script: $HOME/.bashrc for bash terminal and $HOME/.zshrc for zsh

Problem

Simplify, as much as possible, the process to set up my shortcuts every time I migrate to a new computer, personal or work. This process is: download and setups all my scripts in the Bash profile.

Idea

Remember the concept Behavior vs Configuration I explained in my previous post? We are going to continue using it ๐Ÿ˜. Let me list down the main points:

  • Variables are stored in a JSON file. We want those variables to be available during all the terminal sessions.
  • Functions depend on those variables, values that could change depending on the PC your use, for example paths, shouldn't be hard-coded.
  • Both, variables and functions are added in the Bash Profile.

Nice, now that we have the main points, let me show the implementation.

Implementation

First, we have the JSON file containing the variables:

{
"LOCAL_REPOS": "/home/cangulo/repos",
"LOCAL_DOCUMENTS": "/home/cangulo/Documents",
"SCRIPTS_FOLDER": "/home/cangulo/repos/cangulo-blog/cangulo.github.io/blog/posts/bash/4-create-config-repo/code/scripts",
"BOOKMARKS_FILE": "/home/cangulo/repos/cangulo-blog/cangulo.github.io/blog/posts/bash/4-create-config-repo/code/2-bookmarks.json"
}

Each JSON key will be an environment variable, I prefer to define them in upper case to differentiate them from other variables we define during the terminal session.

Then, in the bash profile we only have to do the next actions:

  1. Export the path to the JSON settings. My convention is to call this variable as SETTINGS_FILE.
  2. Call a script to load all the variables and functions using the previous settings. Let's call this script load-custom-profile.sh.

Next is the code for that. Please append it in your profile.

# Update FULL_PATH_TO_JSON_SETTINGS with yours
export SETTINGS_FILE="FULL_PATH_TO_JSON_SETTINGS"
source FULL_PATH/load-custom-profile.sh

Please note we use the export keyword, which sets SETTINGS_FILE as an environment variable. In that way, it will be available for other scripts. Please check this link for more details.

load-custom-profile.sh

This script should perform the next actions:

  • Verify $SETTINGS_FILE is defined and valid:
    • String is not empty
    • Path provided exists
  • Read the JSON file and export the variables. The command is based on jq and eval as explained in my previous post for more details. The main difference now is the use of the export command, following the pattern: export KEY='VALUE'
#!/bin/bash

# verify $SETTINGS_FILE is empty
if [[ -z "$SETTINGS_FILE" ]]; then
echo "no SETTINGS_FILE provided"
return -1
fi

# verify the path at $SETTINGS_FILE exists
if [ ! -f $SETTINGS_FILE ]; then
echo "SETTINGS_FILE path does not exists"
return -1
fi

# export variables
for command in "$(jq -r 'to_entries | .[] | "export " + .key + "=" + (.value | @sh) ' <$SETTINGS_FILE)"; do
eval $command
done

# source functions and aliases
for i in $SCRIPTS_FOLDER/*.sh; do source "$i"; done

# List the bookmarks when opening the terminal
listBookmarks

Next are the scripts stored in $SCRIPTS_FOLDER:

  • aliases:
#!/bin/bash

alias tf="terraform"
alias goToRepos="cd $LOCAL_REPOS"
alias goToDocs="cd $LOCAL_DOCUMENTS"
alias editAwsCredentials="code $HOME/.aws"
alias editBashProfile="code $HOME/.bashrc"

aliases-bash.sh

  • functions:
#!/bin/bash

listBookmarks() {
local pathSelected=$(cat $BOOKMARKS_FILE |
jq -r '.[]' |
fzf)

if [[ -n "$pathSelected" ]]; then
cd $pathSelected
else
echo "no bookmark selected"
fi
}

openRepoUrl() {
local gitUrl=$(git remote get-url --all origin)
local repoUrl="${gitUrl%".git"}" # Removing .git prefix
if [[ -n "$repoUrl" ]]; then
echo "repoUrl:$repoUrl"
xdg-open $repoUrl
fi
}

# REQUIRES fzf, this list the current folder interactively

lsf() {
local chosenDir=$(ls | fzf)
if [[ -n "$chosenDir" ]]; then
cd $chosenDir
fi
}
  • Bookmarks file referenced in the variable BOOKMARKS_FILE , and used in the listBookmarks function:
[
"/home/cangulo/repos/cangulo-tf",
"/home/cangulo/repos/cangulo-nuke"
]

Demo

demo

Repository

If we store the settings and the implementations in a repository (e.g. GitHub) , we just need to reference them in the profile script the same way we have done so far:

# Update LOCAL_REPO_FULL_PATH with yours
export SETTINGS_FILE="LOCAL_REPO_FULL_PATH/settings.local.json"
source LOCAL_REPO_FULL_PATH/load-custom-profile.sh

I recommend you to have a settings.template.json with the empty variables as next:

{
"LOCAL_REPOS": "",
"LOCAL_DOCUMENTS": "",
"SCRIPTS_FOLDER": "",
"BOOKMARKS_FILE": ""
}

In that way, when you clone the repo locally, you duplicate it, rename copy to settings.local.json, and fill the values. Add it to your gitignore to avoid pushing it.

Final Notes

wow, this post is the longest one I have done so far! Do you have another approach for importing scripts or settings? How would you do it? Let me know in the comments below.

About me

I'm a Software Engineer with experience as Developer and DevOps. The technologies I have worked with are DotNet, Terraform and AWS. For the last one, I have the Developer Associate certification. I define myself as a challenge-seeker person and team player. I simply give it all to deliver high-quality solutions. On the other hand, I like to analyze and improve processes, promote productivity and document implementations (yes, I'm a developer that likes to document ๐Ÿง‘โ€๐Ÿ’ป).

You can check my experience here.

Personal Blog - cangulo.github.io
GitHub - Carlos Angulo Mascarell - cangulo
LinkedIn - Carlos Angulo Mascarell
Twitter - @AnguloMascarell

Did you like it? Share It!


Comments