Skip to main content

Load custom variables at Terminal startup

ยท 4 min read
Carlos Angulo Mascarell

In this post, I will explain how to import custom environment variables from a JSON file. I will also improve the shortcuts we create in the previous posts.

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

Variables

Let's say I want to define some variables as:

  • my local github repositories path
  • my documents path
  • path to a specific file, in this case, the path to a JSON file containing some bookmarks I have, check my previous post

By defining them in the profile script as:

# add this at the end of your profile
localRepos="$HOME/repos"
localDocuments="$HOME/Documents"
bookmarksFile="$localRepos/cangulo-blog/cangulo.github.io/blog/posts/bash/3-setup-custom-env-variables/code/4-bookmarks.json"

We can use them during the terminal session.

using the variables after loading the terminal

Let's append the next function and aliases at the bash profile. Please note those are using the variables defined before.

# add this at the end of your profile, after the variables declaration

alias goToRepos="cd $localRepos"
alias goToDocs="cd $localDocuments"

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

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

Now, we can use them after opening the Terminal.

using the variables after loading the terminal

Behavior vs Configuration

In a previous post, the listBookmarks function has the bookmarksFile hardcoded.

listBookmarks() {
local bookmarksFile=./bookmarks.json

As you see, its value refers to the bookmarks.json location. What happens if we move that file to another folder? We would have to update the function. For one variable this doesn't seem to be a problem, right? But what if it is hardcoded in more functions? we would have to update them all, that is not extensible!

Let's define two terms here:

  • Behavior: Functions implementation.
  • Configuration: Input parameters that the function relies on. In this case, bookmarksFile.

By setting all the parameters outside the functions, we are creating a central place for the configuration.

localRepos="$HOME/repos"
localDocuments="$HOME/Documents"
bookmarksFile="$localRepos/cangulo-blog/cangulo.github.io/blog/posts/bash/3-setup-custom-env-variables/code/4-bookmarks.json"

And by calling those from the functions:

listBookmarks() {
local pathSelected=$(cat $bookmarksFile |

We are decoupling configuration from behavior. If we want to migrate or share this setup, we won't need to look at the function implementations, we would only need to update the parameters.

One extra mile: Define the parameters as JSON

Let's migrate the variables to a JSON file as follows. Please note all the paths are now absolute.

{
"localRepos": "/home/cangulo/repos",
"localDocuments": "/home/cangulo/Documents",
"bookmarksFile": "/home/cangulo/repos/cangulo-blog/cangulo.github.io/blog/posts/bash/3-setup-custom-env-variables/code/4-bookmarks.json"
}

To set the JSON keys as the parameters name we have to:

  1. Define the json file path. We will consider those as the main settings.
  2. Use the jq command to retrieve the keys and values.
  3. Use the eval command to execute the key=value for each one.

Next is the solution, replace the variables declaration in your profile for this.

settingsFile="/home/cangulo/repos/cangulo-blog/cangulo.github.io/blog/posts/bash/3-setup-custom-env-variables/code/3-vars.json"
eval "$(jq -r 'to_entries | .[] | .key + "=" + (.value | @sh)' <$settingsFile)"
In case you want to go into the solution details. Click here.

References:

  • Settings json keys as variablesjq. Link
  • What @sh means in jq. Quote string for bash. Link

jq -r 'to_entries' structures the json as key/value pair array:

1-to_entries.png

jq -r 'to_entries | .[]' prepare the array items for the iteration:

2-iterate-over-array-items.png

jq -r 'to_entries | .[] | .key + "=" + .value' build the key=value expressions

3-build-variable-declaration-code.png

jq -r 'to_entries | .[] | .key + "=" + (.value | @sh)' format the expression 4-format-declaration.png

Nothing more for Today! Do you think this is a good approach? 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