• Stars
    star
    156
  • Rank 239,589 (Top 5 %)
  • Language
    Shell
  • License
    MIT License
  • Created over 4 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A framework for creating a Bash CLI application.

bargs

testing

A utility for creating a Bash CLI application.

bargs-demo

Examples

Features

  1. Help Message is auto generated, set bargs > description to update the usage (--help) message

  2. Short and Long Names are supported with name=person_name and short=n

  3. Description Per Argument is supported with description=What is your name?

  4. Flexible Assignment enables passing arguments with the equal sign or a whitespace

    • example.sh --name "Willy Wonka"
    • example.sh --name="Willy Wonka"
  5. Default Value for each argument can be set with default=some-value

    • If default contains whitespaces, use double quotes - default="Willy Wonka"
    • If default starts with a $, then it's a variable
      default=$LANG is evaluted to default=en_US.UTF-8
  6. Allow Environment Variables with allow_env_var=true, if argument is empty then the environment variable will be used. If environment variable is empty, the default will be used

    • Environment variable name must be UPPERCASED, export USERNAME=willywonka
    • Available in your application as $USERNAME or $username
  7. Allow Empty Values with allow_empty=true

  8. Flag Argument with flag=true, if the flag is provided, its value is true - CI=true

  9. Constrain Values is supported with options=first second last, use whitespace as a separator

  10. Prompt for arguments with prompt=true

    • Hide user input with hidden=true
    • Prompt for value confirmation with confirmation=true

Requirements

  • Bash v4.4+
  • Util-Linux - We're printing beautiful stuff with the column command

macOS

brew install util-linux

Ubuntu (Debian)

sudo apt-get -y update && sudo apt-get install -y bsdmainutils

Alpine

apk add --no-cache util-linux bash

CentOS

yum update -y && yum install -y util-linux bash

Windows

Works in Windows-Subsystem-Linux (WSL) using Ubuntu 18.04

More details - Expand/Collapse

Make sure you use dos2unix on all files, see another example here

choco install dos2unix
# ...
dos2unix bargs.sh bargs_vars example.sh tests.sh
# ...
wsl -u root -d Ubuntu-18.04 -- source example.sh

Getting Started

  1. Download bargs.sh (10 kilobytes) and the bargs_vars template

    • Latest version (master)
      curl -sL --remote-name-all bargs.link/{bargs.sh,bargs_vars}
    • Specific release (v1.x.x)
      curl -sL --remote-name-all bargs.link/1.1.4/{bargs.sh,bargs_vars}
  2. Reference to bargs_vars - do one of the following

    • Default behavior - bargs.sh and bargs_vars are in the same folder
    • Specific bargs_vars path - export BARGS_VARS_PATH="${PWD}/path/to/my_bargs_vars", see tests.sh
  3. Edit bargs_vars - Declare arguments/variables, here are some ground rules

    • The delimiter --- is required once at the beginning, and twice in the end
    • Characters which are not supported: =, ~, \, ', "
    • The last variable bargs is necessary, comments below
    • It's best to source bargs at the top of the bash script. Do not add set -o pipefail before source bargs.sh
---
name=bargs                                                # DON'T TOUCH!
description=bash example.sh -n Willy --gender male -a 99  # Editable, that's the usage message
default=irrelevant                                        # DON'T TOUCH!
---
---
bargs_vars - Expand/Collpase
---
name=person_name
short=n
description=What is your name?
default="Willy Wonka"
---
name=age
short=a
description=How old are you?
prompt=true
confirmation=true
---
name=gender
short=g
description=male or female?
options=male female
prompt=true
---
name=location
short=l
description=Where do you live?
default="chocolate factory"
---
name=favorite_food
short=f
allow_empty=true
options=chocolate pizza
description=chocolate or pizza?
---
name=secret
short=s
default=!@#%^&*?/.,[]{}+-|
description=special characters
---
name=language
short=lang
default=$LANG
description=default value can be a variable
---
name=password
short=p
prompt=true
hidden=true
confirmation=true
description=What is your password?
---
name=happy
short=hp
flag=true
description=Flag for indicating that you are happy
---
name=ci
short=ci
flag=true
description=Flag for indicating it is a CI/CD process
---
name=username
short=un
allow_env_var=true
description=Username fetched from environment variable
default=willywonka
---
name=bargs
description=bash example.sh -n Willy --gender male -a 99
default=irrelevant
---
---
  1. Add one of the following lines at the beginning of your application (see Usage below)

    • bargs.sh is in the root folder of your project (just like in this repo)
      source "${PWD}"/"$(dirname ${BASH_SOURCE[0]})"/bargs.sh "$@"
    • bargs.sh is in a subfolder, for example tools
      source "${PWD}"/"$(dirname ${BASH_SOURCE[0]})"/tools/bargs.sh "$@"
  2. The arguments are now available as environment variables, both lowercased and UPPERCASED (see Usage below)

Usage

Using the bargs_vars above in our application - example.sh

#!/bin/bash
source "${PWD}"/"$(dirname ${BASH_SOURCE[0]})"/bargs.sh "$@"

echo "
Name:                  ~ $person_name
Age:                   ~ $age
Gender:                ~ $gender
Location:              ~ $location
Favorite food:         ~ $favorite_food
Secret:                ~ $secret
Password:              ~ $password
OS Language:           ~ $language
I am happy:            ~ $happy
CI Process:            ~ $CI
Uppercased var names:  ~ $PERSON_NAME, $AGE years old, from $LOCATION
Username from env var: ~ $username " \
    | column -t -s "~"

Usage output

Results after running tests.sh - Expand/Collapse
-------------------------------------------------------
[LOG] Bargs Vars Path - Should pass
[LOG] Executing: source example.sh -a 33 --gender male -p mypassword
[LOG] Output:

Name:                     Oompa Looma
Age:                      33
Gender:                   male
Location:                 chocolate factory
Favorite food:            
Secret:                   !@#%^&*?/.,[]{}+-|
Password:                 mypassword
OS Language:              C.UTF-8
I am happy:               
CI Process:               
Uppercased var names:     Oompa Looma, 33 years old, from chocolate factory
Username from env var:    runner 

[LOG] Test passed as expected
-------------------------------------------------------
[LOG] Help Menu - Should pass
[LOG] Executing: source example.sh -h
[LOG] Output:


Usage: bash example.sh -n Willy --gender male -a 99

	--person_name    |  -n     [Willy Wonka]         What is your name?
	--age            |  -a     [REQUIRED]            How old are you?
	--gender         |  -g     [REQUIRED]            male or female?
	--location       |  -l     [chocolate factory]   Where do you live?
	--favorite_food  |  -f     []                    chocolate or pizza?
	--secret         |  -s     [!@#%^&*?/.,[]{}+-|]  special characters
	--language       |  -lang  [C.UTF-8]             default value can be a variable
	--password       |  -p     [REQUIRED]            What is your password?
	--happy          |  -hp    [FLAG]                Flag for indicating that you are happy
	--ci             |  -ci    [FLAG]                Flag for indicating it is a CI/CD process
	--username       |  -un    [willywonka]          Username fetched from environment variable

[LOG] Test passed as expected
-------------------------------------------------------
[LOG] Default Values - Should pass
[LOG] Executing: source example.sh -a 99 --gender=male -p mypassword
[LOG] Output:

Name:                     Willy Wonka
Age:                      99
Gender:                   male
Location:                 chocolate factory
Favorite food:            
Secret:                   !@#%^&*?/.,[]{}+-|
Password:                 mypassword
OS Language:              C.UTF-8
I am happy:               
CI Process:               
Uppercased var names:     Willy Wonka, 99 years old, from chocolate factory
Username from env var:    runner 

[LOG] Test passed as expected
-------------------------------------------------------
[LOG] New Values - Should pass
[LOG] Executing: source example.sh -a 23 --gender male -l=neverland -n meir -p mypassword
[LOG] Output:

Name:                     meir
Age:                      23
Gender:                   male
Location:                 neverland
Favorite food:            
Secret:                   !@#%^&*?/.,[]{}+-|
Password:                 mypassword
OS Language:              C.UTF-8
I am happy:               
CI Process:               
Uppercased var names:     meir, 23 years old, from neverland
Username from env var:    runner 

[LOG] Test passed as expected
-------------------------------------------------------
[LOG] Valid Options - Should pass
[LOG] Executing: source example.sh -a 23 --gender male -l neverland -n meir -f pizza -p=mypassword
[LOG] Output:

Name:                     meir
Age:                      23
Gender:                   male
Location:                 neverland
Favorite food:            pizza
Secret:                   !@#%^&*?/.,[]{}+-|
Password:                 mypassword
OS Language:              C.UTF-8
I am happy:               
CI Process:               
Uppercased var names:     meir, 23 years old, from neverland
Username from env var:    runner 

[LOG] Test passed as expected
-------------------------------------------------------
[LOG] Special Characters - Should pass
[LOG] Executing: source example.sh -a 99 --gender male -s MxTZf+6KHaAQltJWipe1oVRy -p mypassword
[LOG] Output:

Name:                     Willy Wonka
Age:                      99
Gender:                   male
Location:                 chocolate factory
Favorite food:            
Secret:                   MxTZf+6KHaAQltJWipe1oVRy
Password:                 mypassword
OS Language:              C.UTF-8
I am happy:               
CI Process:               
Uppercased var names:     Willy Wonka, 99 years old, from chocolate factory
Username from env var:    runner 

[LOG] Test passed as expected
-------------------------------------------------------
[LOG] Use Flag - Should pass
[LOG] Executing: source example.sh -a 23 --gender male --happy -p mypassword -ci
[LOG] Output:

Name:                     Willy Wonka
Age:                      23
Gender:                   male
Location:                 chocolate factory
Favorite food:            
Secret:                   !@#%^&*?/.,[]{}+-|
Password:                 mypassword
OS Language:              C.UTF-8
I am happy:               true
CI Process:               true
Uppercased var names:     Willy Wonka, 23 years old, from chocolate factory
Username from env var:    runner 

[LOG] Test passed as expected
-------------------------------------------------------
[LOG] Empty Argument - Should fail
[LOG] Executing: source example.sh -a 99 --gender -p mypassword
[LOG] Output:

[HINT] Valid options: male OR female
[ERROR] Invalid value "-p" for the argument "gender"

Usage: bash example.sh -n Willy --gender male -a 99

	--person_name    |  -n     [Willy Wonka]         What is your name?
	--age            |  -a     [REQUIRED]            How old are you?
	--gender         |  -g     [REQUIRED]            male or female?
	--location       |  -l     [chocolate factory]   Where do you live?
	--favorite_food  |  -f     []                    chocolate or pizza?
	--secret         |  -s     [!@#%^&*?/.,[]{}+-|]  special characters
	--language       |  -lang  [C.UTF-8]             default value can be a variable
	--password       |  -p     [REQUIRED]            What is your password?
	--happy          |  -hp    [FLAG]                Flag for indicating that you are happy
	--ci             |  -ci    [FLAG]                Flag for indicating it is a CI/CD process
	--username       |  -un    [willywonka]          Username fetched from environment variable

[LOG] Test failed as expected
-------------------------------------------------------
[LOG] Unknown Argument - Should fail
[LOG] Executing: source example.sh -a 99 -u meir -p mypassword
[LOG] Output:

[ERROR] Unknown argument "-u"

Usage: bash example.sh -n Willy --gender male -a 99

	--person_name    |  -n     [Willy Wonka]         What is your name?
	--age            |  -a     [REQUIRED]            How old are you?
	--gender         |  -g     [REQUIRED]            male or female?
	--location       |  -l     [chocolate factory]   Where do you live?
	--favorite_food  |  -f     []                    chocolate or pizza?
	--secret         |  -s     [!@#%^&*?/.,[]{}+-|]  special characters
	--language       |  -lang  [C.UTF-8]             default value can be a variable
	--password       |  -p     [REQUIRED]            What is your password?
	--happy          |  -hp    [FLAG]                Flag for indicating that you are happy
	--ci             |  -ci    [FLAG]                Flag for indicating it is a CI/CD process
	--username       |  -un    [willywonka]          Username fetched from environment variable

[LOG] Test failed as expected
-------------------------------------------------------
[LOG] Invalid Options - Should fail
[LOG] Executing: source example.sh -a 23 --gender male -l neverland -n meir -f notgood -p mypassword
[LOG] Output:

[HINT] Valid options: chocolate OR pizza
[ERROR] Invalid value "notgood" for the argument "favorite_food"

Usage: bash example.sh -n Willy --gender male -a 99

	--person_name    |  -n     [Willy Wonka]         What is your name?
	--age            |  -a     [REQUIRED]            How old are you?
	--gender         |  -g     [REQUIRED]            male or female?
	--location       |  -l     [chocolate factory]   Where do you live?
	--favorite_food  |  -f     []                    chocolate or pizza?
	--secret         |  -s     [!@#%^&*?/.,[]{}+-|]  special characters
	--language       |  -lang  [C.UTF-8]             default value can be a variable
	--password       |  -p     [REQUIRED]            What is your password?
	--happy          |  -hp    [FLAG]                Flag for indicating that you are happy
	--ci             |  -ci    [FLAG]                Flag for indicating it is a CI/CD process
	--username       |  -un    [willywonka]          Username fetched from environment variable

[LOG] Test failed as expected
-------------------------------------------------------
[LOG] Missing bargs_vars - Should fail
[LOG] Executing: source example.sh -h
[LOG] Output:

[ERROR] Make sure bargs_vars is in the same folder as bargs.sh
	Another option - export BARGS_VARS_PATH="/path/to/my_bargs_vars"

[LOG] Test failed as expected

Package your application with Docker

You can use Docker to package your Bash script as a Docker image, see the following example

  1. Clone this repository

  2. Build the image, see Dockerfile.example, tag it bargs:example

    docker build -f Dockerfile.example -t bargs:example .
  3. Run a container that is based on the image above

    docker run --rm -it bargs:example -a 23 -g male

Use this repository as a template

Thinking of writing a new Bash script? Hit the Use this template button and get a fully working example of bargs, including GitHub Actions workflows.

Contributing

Report issues/questions/feature requests on the Issues section.

Pull requests are welcome! These are the steps:

  1. Fork this repo
  2. Create your feature branch from master (git checkout -b my-new-feature)
  3. Add the code of your new feature
  4. Run tests on your code, feel free to add more tests
    bash tests.sh
    ... # All good? Move on to the next step
  5. Commit your remarkable changes (git commit -am 'Added new feature')
  6. Push to the branch (git push --set-up-stream origin my-new-feature)
  7. Create a new Pull Request and provide details about your changes

Authors

Created and maintained by Meir Gabay

License

This project is licensed under the MIT License - see the LICENSE file for details

More Repositories

1

kubernetes-localdev

Create a local Kubernetes development environment on macOS or Windows and WSL2, including HTTPS/TLS and OAuth2/OIDC authentication.
220
star
2

terraform-multienv

A template for maintaining a multiple environments infrastructure with Terraform. This template includes a CI/CD process, that applies the infrastructure in an AWS account.
Shell
141
star
3

install-aws-cli-action

Install AWS CLI on a GitHub Actions Linux host
Shell
60
star
4

githubsecrets

Manage your GitHub Actions secrets with a simple CLI
Python
43
star
5

aws-build-badges

Create AWS status/commit-id badges for CodeBuild & CodePipeline automatically
TypeScript
40
star
6

frigga

Scrape only relevant metrics in Prometheus, according to your Grafana dashboards
Python
22
star
7

serverless-template

Boilerplate template for the serverless-framework
Python
15
star
8

tfcoding

Render Terraform's Expressions and Functions locally without any hassle.
Shell
10
star
9

iamlive-docker

The source code for building iamlive Docker image
Shell
9
star
10

replacer

Find and replace multiline strings
Shell
8
star
11

yarser

A CLI for parsing YAML anchors to regular YAML files.
Go
7
star
12

nexus-ops

Provisioning a preconfigured Nexus Repository Manager (NXRM) Docker container.
Shell
7
star
13

docker-cats

A simple web application that serves different content according to a given environment variable.
Python
5
star
14

terraform-aws-ssm-parameters

Create AWS SSM Parameter Store parameters with a Terraform module. The creation/deletion (schema) is managed with Terraform, and the values should be maintained via AWS Console.
HCL
5
star
15

pwa-quasar-local

This project demonstrates how to develop a Progressive Web Application (PWA) locally on an Android device, using the Quasar Framework v2.
JavaScript
4
star
16

parzival

A CLI that can get/set more than 10 SSM Parameters by path in a single command.
Go
4
star
17

bash-logging

A Logging Framework for Bash. This project aims to provide a solution that can be implemented with a single file import `source logging.sh`.
Shell
3
star
18

aws-sdk-golang-examples

How to use AWS SDK in Go for developers who want to get started with Go
Go
3
star
19

aws-webui

A Single Page Application to manage AWS resources efficiently.
Vue
3
star
20

python-project

Python project structure, relative imports, absolute imports, packages, and modules. Let's make it simpler.
Python
3
star
21

replacer-action

Auto-update README.md file according to the source code.
Shell
3
star
22

alpine-ci

Docker image of Linux alpine, mostly suited for simple CI tasks
Dockerfile
2
star
23

modulecost

Calculate Terraform modules cost, implemented with infracost
Shell
2
star
24

csod-automation

Automating adminstrative tasks in CornerStone On-Demand
Python
2
star
25

unfor19

2
star
26

meetup-31-jan-2023

Microsoft Reactor Meetup - https://www.meetup.com/thecircle/events/290984564/
JavaScript
2
star
27

configmap-action

Exports configmap.json as a job-output according to a given key, such as `GIT_BRANCH` or `DEPLOYMENT_ENVIRONMENT`, which is later consumed by other jobs with "needs".
Shell
2
star
28

tf-tutorial-workspaces

Learn how to use Terraform Cloud and Workspaces
HCL
1
star
29

install-aws-cli-action-test

1
star
30

configmap-action-test

1
star
31

terraform-meetup-live

HCL
1
star
32

kubemanny

Multiple packages for managing your AWS EKS cluster, and deploying Kubeless functions
Shell
1
star
33

devops-genin

A DevOps challenge that will grant you the title Genin (Starter).
1
star
34

terraform-cwagent-ecs-instance-metric

Terraform AWS ECS CloudWatch Agent on ECS
HCL
1
star
35

ecs-stop-task

Shell
1
star