TL;DR: bargs - A featherweight Bash package, which enables an easy way to use command line arguments in your Bash scripts
Every time I need to write a Bash script which accepts command line arguments, I go back to this great answer in StackOverflow - How do I parse command line arguments in Bash
Let's do a quick overview of the process!
The usual way
So here I am, maintaining the command line arguments, which in turn, will be variables, in four different places. Why four? Here we go!
1 - usage function
The usage
function should pop up whenever the user attempts to provide wrong or missing arguments
usage()
{
cat << EOF
usage: bash ./scripts/packndeploy -n service_name
-n | --service_name (Required) Service to deploy
-b | --branch (master) Source branch
-h | --help Brings up this menu
EOF
}
2 - Declaring Variables
To get the command line arguments, we need to declare variables that can store them, and also set the default values for these variables/arguments.
service_name=
branch=master # default value
3 - Arguments to Variables
Mapping arguments to variables with while case shift
is a great trick to fetch variables! To learn more about it read this great tutorial or this great comment in StackOverflow
while [ "$1" != "" ]; do
case $1 in
-n | --service_name )
shift
service_name=$1
;;
-b | --branch )
shift
branch=$1
-h | --help ) usage
exit
;;
* ) usage
exit 1
esac
shift
done
4 - Verifying required arguments
After the while
loop above βοΈ we need to make sure that the required variables were provided. So here's a quick and dirty way to do it
if [ -z $service_name ]; then
echo "Service name is required, provide it with the flag: -n service_name"
exit
fi
NOTE: I'm sure that it's better to write a function that performs some of the tasks above dynamically, but it still means we need to write it or copy-paste it to our Bash script.
Motivation
I'm writing a lot of Bash scripts, and most of them require command line arguments, so I thought it'd be best to write a "wrapper script" that performs all the above-mentioned steps.
The "wrapper script" should meet the following requirements
- Manage all arguments, including the variables that they become in one place
-
A beautiful usage or help message that is based on the definitions of the arguments. We'll get to that, I call it
bargs_vars
- Adding the "wrapper script" by performing minimum steps and without polluting my Bash script
The Solution - bargs
Ladies and gentlemen, I present to you bargs - a comfortable way to deal with command line arguments in Bash.
So how do you use it? Keep on reading or jump to the bargs GitHub repository to get started!
Requirements
- Bash v4.4+
- Linux Utils - We're printing beautiful stuff with the column command, that is included in Linux Utils
macOS
$ brew install util-linux
Linux (Debian/Ubuntu)
$ sudo apt-get -y update && sudo apt-get install -y bsdmainutils
Windows
Not supported (yet)
Getting Started
- Download the script (4 kilobytes) and put it in the same folder as your code
curl -s -L bargs.link/bargs.sh --output bargs.sh
-
Creating bargs_vars - do one of the following
- Create the file
bargs_vars
, put it in the same folder asbargs.sh
- Download the existing
bargs_vars
template
curl -s -L bargs.link/bargs_vars --output bargs_vars
- Create the file
Declaring arguments/variables
- The delimiter
---
is required once at the beginning, and twice in the end - If the default is empty or not defined, the argument is required
- You can't add comments to this file, use the description
- Arguments values (including default) must not contain whitespace
- Use the bargs description to set the
--help
message
---
name=person_name
short=n
description=What is your name?
default=Willy
---
name=age
short=a
---
name=gender
short=g
---
name=location
short=l
description=insert your location
default=chocolate-factory
---
name=bargs
description=bash example.sh -n Willy --gender male -a 99
---
---
- Add the following line at the beginning of your application
source bargs.sh "$@"
- That's it! You can now reference to arguments that were declared in
bargs_vars
Usage
Using the bargs_args
above in our application - example.sh
#!/bin/bash
source bargs.sh "$@"
echo -e \
"Name:~$person_name\n"\
"Age:~$age\n"\
"Gender:~$gender\n"\
"Location:~$location" | column -t -s "~"
Usage output
- Using the help flag
bash example.sh -h
Usage: bash example.sh -n Willy --gender male -a 99
--person_name | -n [Willy] What is your name?
--age | -a [Required]
--gender | -g [Required]
--location | -l [chocolate-factory] insert your location
- Using default values
$ bash example.sh -a 99 --gender male
Name: Willy
Age: 99
Gender: male
Location: chocolate-factory
- Providing all arguments
$ bash example.sh -a 23 --gender male -l neverland -n meir
Name: meir
Age: 23
Gender: male
Location: neverland
- Providing an empty required argument
$ bash example.sh -a 99 --gender
[ERROR] Empty argument: gender
Usage: bash example.sh -n Willy --gender male -a 99
--person_name | -n [Willy] What is your name?
--age | -a [Required]
--gender | -g [Required]
--location | -l [chocolate-factory] insert your location
- Providing an unknown argument
$ bash example.sh -a 99 -u meir
[ERROR] Unknown argument: -u
Usage: bash example.sh -n Willy --gender male -a 99
--person_name | -n [Willy] What is your name?
--age | -a [Required]
--gender | -g [Required]
--location | -l [chocolate-factory] insert your location
Final words
I hope that using bargs will assist you in writing a bash script and parsing command line arguments.
Feel free to ask questions, I've already answered a few in this reddit post, so keep 'em coming. The community feedback is what makes open-source projects better, so I urge you to doubt and ask questions! :)
Liked this blog post? Thank you! Don't forget to π/π/π΄ and share!
Top comments (0)