Automating My Workflow:
How I Use Bash and Shell Scripting to Work Smarter

Published on: April 2, 2025

A bit of history

I fell in love with the terminal during my first job as a junior developer. My CTO at the time was nothing short of a wizard.

He worked magic on an old, battered MacBook Air, yet managed to accomplish everything effortlessly.

It didn’t take long for me to notice his secret: he never actually coded on his laptop. Instead, he used it as a gateway, SSHing into a high-performance EC2 instance. From there, he opened vi (not even vim!) and began typing away. In a single SSH session, he developed, tested, and deployed all the backend services for our startup.

I picked up a few tutorials on the basics of vim. And haven't looked back ever since.

Here are a few ways I leverage bash and shell scripting

Developer Environment Setup

Setting up a new development environment can be tedious, especially with numerous tools and plugins

Here’s a snippet of a script I use to set up my development environment.

bash
#!/usr/bin/env bash

install_java() {
	if [ -n "$(command -v java)" ]; then
		echo 'Java already installed'
	else
		echo 'Installing Java'
		brew install java
		sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk \
      /Library/Java/JavaVirtualMachines/openjdk.jdk
	fi
	if ! [ -d '/opt/homebrew/opt/openjdk@22/libexec/openjdk.jdk/Contents/Home' ];
	then
		echo 'Creating Java 22'
		brew install openjdk@22
		sudo ln -sfn /opt/homebrew/opt/openjdk@22/libexec/openjdk.jdk \
			/Library/Java/JavaVirtualMachines/openjdk-22.jdk
	fi
}

install_java_packages() {
	if [ -n "$(command -v ant)" ]; then
		echo 'Ant already installed'
	else
		echo 'Installing Ant'
		brew install ant
	fi
	...
}

install_lua
install_python
install_neovim
install_node
install_yarn
install_ruby
install_ruby_packages
install_rust
install_rust_sub_packages
install_java
install_java_packages
install_tmux
install_oh_my_zsh
install_go
install_markdown_preview
...

exec "$HOME/.config/bin/dev_setup" 

Now I just need to clone my repository into the new machine, run the following command, and I’m good to go.

bash
setup

This script does the following:

  1. Sets up my terminal they way I like it (ZSH, Kitty, TMUX, etc.)
  2. Uses native package managers to install all the languages I use (Java, Node, Rust, Go, etc.)
  3. Setups my Neovim environment
  4. Links all the .dotfiles I need, puts them in the right place

Git wrappers

Beyond this I use bash and shell scripting is to create wrappers for Git commands. These are some of the wrappers I use on a daily basis:

bash
# Smarter git checkout (figures out if branch exists in remote with same name)
$ g-co -t feature/xyz

1. Checking pre-requisites [In Progress]
   > Checking pre-requisites [Done]
2. Stash changes [Skipped]
3. Check out to branch feature/xyz [In Progress]
   > Checking if branch exists in remote...
   > Branch with name does not exist.
     Do you want to create a new branch? (Y/n): y
	 > Switched to a new branch 'feature/xyz'
   > Created new local branch feature/xyz. [DONE]

Log file: /Users/santhosh/.config/bin/.g-co.log
Error log file: /Users/santhosh/.config/bin/.g-co-error.log

# Smarter git push (figures out which branch to push to)
$ g-push

# Smarter git pull (figures out which branch to pull from, unless specified)
$ g-pull
$ g-pull -t feature/xyz

# Reset local branch to remote (cleans up your git tree)
$ g-rto

# Add git worktree
$ g-wa -b develop -p ../develop;

# and so on...

Simplifying complex build processes

Another way I use bash and shell scripting is to simplify complex build processes. For example, I have a script that automates the building and deployment of my applications.

For example, At Whatfix, we have a complex dev environment setup. Doing it manually every time you need a fresh setup is a pain. So I automated away the pain (for the most part) with a script that does the setup for me.

Here is a runtime preview of the script:

bash
$setup_wfx_repo
__        _________  __  ____  _____ _____ _   _ ____  
\ \      / /  ___\ \/ / / ___|| ____|_   _| | | |  _ \ 
 \ \ /\ / /| |_   \  /  \___ \|  _|   | | | | | | |_) |
  \ V  V / |  _|  /  \   ___) | |___  | | | |_| |  __/ 
   \_/\_/  |_|   /_/\_\ |____/|_____| |_|  \___/|_|    
                                                       
Checking pre-requisites...
All pre-requisites are satisfied. [DONE]
All repositories are in place

fix_all_repos: y
stash_changes: y
skip_branch_checkout: n
branch: develop
fallback_branch: master
sync_with_remote_branch: n
skip_module_x: n
skip_module_y: n
...
point_to: uataz

Use current configuration (Y/n): n
Skip branch checkout (Y/n):
Fix all repos (Y/n):
Point to (uataz): prod

Fixing module_x
  - Updating yarn and yalc path
  - Removing <module> build
  - Updating .info file
  - Removing firefox and safari build
  - Fixing .properties file
  - Set /Users/santhosh.kumarsiva/.nvm/versions/node/v21.6.0/bin/yarn
		and /opt/homebrew/bin/yalc paths
  - Fixed <module> errors
  - Updated wfx info to use subdomain.domain.com
  - Removed edge, firefox and safari builds

...

Done

How to get started?

If you’re new to bash and shell scripting, here are a few tips to get started:

  • Learn the basics of bash and shell scripting. There are plenty of resources available online, including tutorials, courses, and documentation. (I recommend this course Linux Mastery: Master the Linux Command Line in 11.5 Hours).
  • Start small, try automating simple tasks first.
  • Maintain a library of scripts that you can reuse. I have a repository of scripts that I use on a daily basis. I keep them in a private repository on GitHub, and I can easily clone them to any new machine.
  • Humanize with prompts and progress bars, if your script is being used by others.
  • Switch to Python or Node.js for more complex tasks. Thar require data manipulation or more advanced logic.

Tools to make your terminal experience better

Here are a few tools that I use to make my life easier:

  • Tmux and tmux/resurrect, ensures I never lose my sessions, even after a crash.
  • ZSH and oh-my-zsh, a must have for every developer.
  • Use Copilot CLI to help you on the terminal when you are stuck.

Conclusion

Bash and shell scripting are powerful tools that can help you automate your daily tasks and improve your productivity. By leveraging these tools, you can streamline your workflow and focus on the tasks that matter most.

What tasks in your workflow could you automate today? Start small, experiment, and see how scripting can make your life easier.