bash-plusplus

bash ++

This is a framework to bring bash to a next level.
Check out the examples »

Project status · Report Bug · Contribute code

Index

What is bash++ ?

Bash++ is a new way to bring bash to a next level. This framework introduces new functionalities to bash. Some of this functionalities are:

Bash++ is designed so that people could build more complex apps creating better products. Note that this project is for people with experience with bash (not much, just simple understandings and how things usually work).

When you run bash++ with bash, the application breaks. This is why you need to add #!/usr/bash to the start of the script (see instructions here).

Bash haves it’s own module system, so you will have a bash++ folder in your /usr/libs directory (just so that you know).

(back to top)

Installation

To use bash++ you will (obviously) need to install it. To install it, clone the repo by running the following command:

git clone https://github.com/mauro-balades/bash-plusplus

After cloning the repository, cd into that directory. Once you are in the directory called bash++. Run the following command to proceed with the installation.

Note that you need to run it as root.

sudo make install

When you have installed it, you will see a new directory (usually in /usr/lib/bash++). This directory is where all of bash’s built-in libraries will be stored.

Q/A

What’s the point when python, perl and other more robust scripting languages exist?

This is something that comes up really often, I’ve found that Oil Shell main FAQ covers this topic thoroughly:

Be sure to check out Oil in more detail if you can, it’s a very impressive project.

Usage

We all need to start somewhere, in this section you will se on how to use every functionality in bash++.

Getting started

To get started, create a bash script (or an existing one). Add the following shebang at the start of the file so that bash can know what file you use.

#!/bin/bash

After you have added the shebang, chmod the main script with:

chmod +x [SCRIPT_NAME].sh

Then, you can just simply run the script as:

./[SCRIPT_NAME].sh

NOTE: Replace [SCRIPT_NAME] with your main bash script.

(back to top)

Bootstrap the project

To bootstrap your script you will need to source the Import script in your libs folder.

. "${BASHPP_LIBS}/Import.sh" # Source bash++

NOTE: Only do this step once (aka in the main script). and you will need to put in at the top of the file.

(back to top)

Functionalities

Humans need help to learn something new, that is why in this section all bash++ functionalities will be explained with an example.

Import

Normal bash developers will use . or source to ‘import’ a bash script. Professional Bash++ developers will use the import function.

The Import function will let you choose more variation of sourcing methods that some developers will kill to have that. Apart from it giving more functionality it also creates new (or experienced) bash users a better syntax reading.

The following code is the function declaration for import:

# ImportService::Import (import)
#
# Usage:
#   import MyFile
#   import System # Builtin module
#   import github:mauro-balades/bash-plusplus
#   import https://example.com/script.sh
#   import script1 script2 ...
#
# Description:
#   This function is used to import your bash script.
#   The function is a replacement for "source" since
#   it contains more functionality and it makes the
#   code prettier
#
# Arguments:
#   [...any] scripts: Bash scripts to be imported
ImportService::Import() {
  ...
}

As you can see from the function declaration, import can be used in different ways such as:

Description:

Usage:

NOTE: It adds the script to an array of imported files. If you get an error saying that a file has already been sourced, remove that file from the import function since it already exists.

(back to top)

Import’s extended API

Bash++ also exports some extra features from the import API.

alias import="ImportService::Import"

# Overrides
alias .="ImportService::SimpleImport"
alias source="ImportService::SimpleImport"

# Extending the API
alias import.url="ImportService::ImportUrl"
alias import.github="ImportService::ImportGitHub"
alias import.simple="ImportService::SimpleImport" # Same as source and .

# Utility functions
alias import.exists="ImportService::Exists"
alias import.nexists="ImportService::NExists"

alias import.addm="ImportService::AddModule"

Feel free to check out the src/Import.sh file to see each function declaration (it’s description, arguments and usage).

(back to top)

Classes

Classes are the main purpose of this project. To create a class, you will need to import a built-in module called Classes


# BOOTSTRAP ALREADY DONE ABOVE (IMAGINE)

import Classes

To define a class, it is like defining a normal variable except you have “attributes” inside it.


# BOOTSTRAP ALREADY DONE ABOVE (IMAGINE)

import Classes

MyClass=(

  function __new__ # When class is initiated
  function __delete__ # At the end of the script this is called

  function hello
  function hi = MyClass::different_function # If you call the function "hi", it will actually call MyClass::different_function

  declare name
) # Class called "MyClass"

Great, you have successfully declared a class (joke). To add functionality, how about declaring what the function will do. By the way, functions __new__ and __delete__ are completely optional.


# BOOTSTRAP ALREADY DONE ABOVE (IMAGINE)

import Classes

MyClass=(

  function __new__ # When class is initiated
  function __delete__ # At the end of the script this is called

  function hello
  function hi = MyClass::different_function # If you call the function "hi", it will actually call MyClass::different_function

  declare name
) # Class called "MyClass"

MyClass::__new__() {
  # Get the "self" value
  # Explained in the paragraph bellow.
  local self=$1
  shift

  echo "class has inited"

  # Set name to the first argument we get
  # NOTE that name is declared above
  # with the declare keyword
  #
  # "$1" was the self argument
  # but now, we shifter so that function
  # can hav arguments like a normal function
  $self.name= "$1"
}

MyClass::__delete__() {
  echo "Good Bye!"
}

MyClass::hello() {
  local self=$1
  shift

  NAME=$($self.name)
  echo "Hello, $NAME"
}

# Called with the "hi" function
MyClass::different_function() {
  local self=$1
  shift

  echo "Hi, $($self.name)"
}

(back to top)

Initiate a class

To create a new instance of a class, you will use the new function. In the new function, you need to add a class name, a new variable in which it is going to be created with that name and arguments that can be passed to the __new__ function.

Example (with context of the last example above):

#   | Class name     | Arguments passed to __new__ (can be infinite)
new MyClass my_class Rob
# ^         ^ new var to create with class instance

(back to top)

Call class’ attributes

When you have created a new instance of a class, a variable is made so that you can access this functions and variables.

example:

$my_class.hello # arguments separated by spaces

and to access class’ variables:

VAR=$($my_class.name)

(back to top)

.env

To import enviromental variables, you will need to include the dotenv module.

import dotenv

This will give you acces to the load_dotenv function. This functions has 1 optional parameter. That paramenter is the name of your .env file.

load_dotenv

# or
load_dotenv "path/to/.env"

(back to top)

License

# ================================ BASH ++ ================================
#
#    ...............................................
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@.(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@      @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@      #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@@@       @@@@@@@@@@@@@@@@@@@@@@@@  @@@   @@
#    @@@@@@@@@@@@@      ,@@@@@@@@@@@@@@@@@@@@      @ @@@@@@
#    @@@@@@@@@@.      @@@@@@@@@@@@@@@@@@@@@@@@@  @@@   @@
#    @@@@@@@@      .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@    @@@@@@@@             #@@@@@@@@@@@@@
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&
#
# Copyright <Mauro Baladés> 2021
# Bash++ Is under the license of "GNU GENERAL PUBLIC LICENSE
# =========================================================================

(back to top)