Bash library which provides utility functions and helpers for functional programming in Bash.
Detailed documentation is available at https://labbots.github.io/bash-utility
The script can be installed and sourced using following methods.
If the library is used inside a git project then git submodules can be used to install the library to the project.
Following command will initialize git submodule and download the library to ./vendor/bash-utility
folder.
git submodule init
git submodule add -b master https://github.com/labbots/bash-utility vendor/bash-utility
To Update submodules to latest code execute the following command.
git submodule update --rebase --remote
Once the submodule is added or updated, make sure to commit changes to your repository.
git add .
git commit -m 'Added/updated bash-utility library.'
Note: When cloning your repository, use --recurse-submodules
flag to git clone
command to install the git sub modules.
If you don’t want to use git submodules, you can use git clone
to download library and then move the files to desired location manually.
The below command will clone the repository to vendor/bash-utility
folder in current working directory.
git clone https://github.com/labbots/bash-utility.git ./vendor/bash-utility
If you do not have git installed, you can download the archive of the latest version of the library. Extract the zip file to appropriate folder by following the below command.
wget https://github.com/labbots/bash-utility/archive/master.zip
unzip -q master.zip -d tmp
mkdir -p vendor/bash-utility
mv tmp/bash-utility-master vendor/bash-utility
rm tmp
Bash utility functions can be used by simply sourcing the library script file to your own script.
To access all the functions within the bash-utility library, you could import the main bash file as follows.
source "vendor/bash-utility/bash-utility.sh"
You can also only use the necessary library functions by only importing the required function files.
source "vendor/bash-utility/src/array.sh"
Functions for array operations and manipulations.
Check if item exists in the given array.
array=("a" "b" "c")
array::contains "c" ${array[@]}
#Output
0
Remove duplicate items from the array.
array=("a" "b" "a" "c")
printf "%s" "$(array::dedupe ${array[@]})"
#Output
a
b
c
Check if a given array is empty.
array=("a" "b" "c" "d")
array::is_empty "${array[@]}"
Join array elements with a string.
array=("a" "b" "c" "d")
printf "%s" "$(array::join "," "${array[@]}")"
#Output
a,b,c,d
printf "%s" "$(array::join "" "${array[@]}")"
#Output
abcd
Return an array with elements in reverse order.
array=(1 2 3 4 5)
printf "%s" "$(array::reverse "${array[@]}")"
#Output
5 4 3 2 1
Returns a random item from the array.
array=("a" "b" "c" "d")
printf "%s\n" "$(array::random_element "${array[@]}")"
#Output
c
Sort an array from lowest to highest.
sarr=("a c" "a" "d" 2 1 "4 5")
array::array_sort "${sarr[@]}"
#Output
1
2
4 5
a
a c
d
Sort an array in reverse order (highest to lowest).
sarr=("a c" "a" "d" 2 1 "4 5")
array::array_sort "${sarr[@]}"
#Output
d
a c
a
4 5
2
1
Bubble sort an integer array from lowest to highest.
This sort does not work on string array.
iarr=(4 5 1 3)
array::bsort "${iarr[@]}"
#Output
1
3
4
5
Merge two arrays.
Pass the variable name of the array instead of value of the variable.
a=("a" "c")
b=("d" "c")
array::merge "a[@]" "b[@]"
#Output
a
c
d
c
Helper functions.
Check if the command exists in the system.
check::command_exists "tput"
Check if the script is executed with sudo privilege.
Function has no arguments.
check::is_sudo
(Experimental) Functions to iterates over a list of elements, yielding each in turn to an iteratee function.
Iterates over elements of collection and invokes iteratee for each element.
Input to the function can be a pipe output, here-string or file.
test_func(){
printf "print value: %s\n" "$1"
return 0
}
arr1=("a b" "c d" "a" "d")
printf "%s\n" "${arr1[@]}" | collection::each "test_func"
collection::each "test_func" < <(printf "%s\n" "${arr1[@]}") #alternative approach
#output
print value: a b
print value: c d
print value: a
print value: d
# If other function from this library is already used to process the array.
# Then following method could be used to pass the array to the function.
out=("$(array::dedupe "${arr1[@]}")")
collection::each "test_func" <<< "${out[@]}"
Checks if iteratee function returns truthy for all elements of collection. Iteration is stopped once predicate returns false.
Input to the function can be a pipe output, here-string or file.
arri=("1" "2" "3" "4")
printf "%s\n" "${arri[@]}" | collection::every "variable::is_numeric"
Iterates over elements of array, returning all elements where iteratee returns true.
Input to the function can be a pipe output, here-string or file.
arri=("1" "2" "3" "a")
printf "%s\n" "${arri[@]}" | collection::filter "variable::is_numeric"
#output
1
2
3
Iterates over elements of collection, returning the first element where iteratee returns true.
Input to the function can be a pipe output, here-string or file.
arr=("1" "2" "3" "a")
check_a(){
[[ "$1" = "a" ]]
}
printf "%s\n" "${arr[@]}" | collection::find "check_a"
#Output
a
Invokes the iteratee with each element passed as argument to the iteratee.
Input to the function can be a pipe output, here-string or file.
opt=("-a" "-l")
printf "%s\n" "${opt[@]}" | collection::invoke "ls"
Creates an array of values by running each element in array through iteratee.
Input to the function can be a pipe output, here-string or file.
arri=("1" "2" "3")
add_one(){
i=${1}
i=$(( i + 1 ))
printf "%s\n" "$i"
}
printf "%s\n" "${arri[@]}" | collection::map "add_one"
The opposite of filter function; this method returns the elements of collection that iteratee does not return true.
Input to the function can be a pipe output, here-string or file.
arri=("1" "2" "3" "a")
printf "%s\n" "${arri[@]}" | collection::reject "variable::is_numeric"
#Ouput
a
Checks if iteratee returns true for any element of the array.
Input to the function can be a pipe output, here-string or file.
arr=("a" "b" "3" "a")
printf "%s\n" "${arr[@]}" | collection::reject "variable::is_numeric"
Functions for manipulating dates.
Get current time in unix timestamp.
Function has no arguments.
echo "$(date::now)"
#Output
1591554426
convert datetime string to unix timestamp.
echo "$(date::epoc "2020-07-07 18:38")"
#Output
1594143480
Add number of days from specified timestamp.
If number of days not specified then it defaults to 1 day.
echo "$(date::add_days_from "1594143480")"
#Output
1594229880
Add number of months from specified timestamp.
If number of months not specified then it defaults to 1 month.
echo "$(date::add_months_from "1594143480")"
#Output
1596821880
Add number of years from specified timestamp.
If number of years not specified then it defaults to 1 year.
echo "$(date::add_years_from "1594143480")"
#Output
1625679480
Add number of weeks from specified timestamp.
If number of weeks not specified then it defaults to 1 week.
echo "$(date::add_weeks_from "1594143480")"
#Output
1594748280
Add number of hours from specified timestamp.
If number of hours not specified then it defaults to 1 hour.
echo "$(date::add_hours_from "1594143480")"
#Output
1594147080
Add number of minutes from specified timestamp.
If number of minutes not specified then it defaults to 1 minute.
echo "$(date::add_minutes_from "1594143480")"
#Output
1594143540
Add number of seconds from specified timestamp.
If number of seconds not specified then it defaults to 1 second.
echo "$(date::add_seconds_from "1594143480")"
#Output
1594143481
Add number of days from current day timestamp.
If number of days not specified then it defaults to 1 day.
echo "$(date::add_days "1")"
#Output
1591640826
Add number of months from current day timestamp.
If number of months not specified then it defaults to 1 month.
echo "$(date::add_months "1")"
#Output
1594146426
Add number of years from current day timestamp.
If number of years not specified then it defaults to 1 year.
echo "$(date::add_years "1")"
#Output
1623090426
Add number of weeks from current day timestamp.
If number of weeks not specified then it defaults to 1 year.
echo "$(date::add_weeks "1")"
#Output
1592159226
Add number of hours from current day timestamp.
If number of hours not specified then it defaults to 1 hour.
echo "$(date::add_hours "1")"
#Output
1591558026
Add number of minutes from current day timestamp.
If number of minutes not specified then it defaults to 1 minute.
echo "$(date::add_minutes "1")"
#Output
1591554486
Add number of seconds from current day timestamp.
If number of seconds not specified then it defaults to 1 second.
echo "$(date::add_seconds "1")"
#Output
1591554427
Subtract number of days from specified timestamp.
If number of days not specified then it defaults to 1 day.
echo "$(date::sub_days_from "1594143480")"
#Output
1594057080
Subtract number of months from specified timestamp.
If number of months not specified then it defaults to 1 month.
echo "$(date::sub_months_from "1594143480")"
#Output
1591551480
Subtract number of years from specified timestamp.
If number of years not specified then it defaults to 1 year.
echo "$(date::sub_years_from "1594143480")"
#Output
1562521080
Subtract number of weeks from specified timestamp.
If number of weeks not specified then it defaults to 1 week.
echo "$(date::sub_weeks_from "1594143480")"
#Output
1593538680
Subtract number of hours from specified timestamp.
If number of hours not specified then it defaults to 1 hour.
echo "$(date::sub_hours_from "1594143480")"
#Output
1594139880
Subtract number of minutes from specified timestamp.
If number of minutes not specified then it defaults to 1 minute.
echo "$(date::sub_minutes_from "1594143480")"
#Output
1594143420
Subtract number of seconds from specified timestamp.
If number of seconds not specified then it defaults to 1 second.
echo "$(date::sub_seconds_from "1594143480")"
#Output
1594143479
Subtract number of days from current day timestamp.
If number of days not specified then it defaults to 1 day.
echo "$(date::sub_days "1")"
#Output
1588876026
Subtract number of months from current day timestamp.
If number of months not specified then it defaults to 1 month.
echo "$(date::sub_months "1")"
#Output
1559932026
Subtract number of years from current day timestamp.
If number of years not specified then it defaults to 1 year.
echo "$(date::sub_years "1")"
#Output
1591468026
Subtract number of weeks from current day timestamp.
If number of weeks not specified then it defaults to 1 week.
echo "$(date::sub_weeks "1")"
#Output
1590949626
Subtract number of hours from current day timestamp.
If number of hours not specified then it defaults to 1 hour.
echo "$(date::sub_hours "1")"
#Output
1591550826
Subtract number of minutes from current day timestamp.
If number of minutes not specified then it defaults to 1 minute.
echo "$(date::sub_minutes "1")"
#Output
1591554366
Subtract number of seconds from current day timestamp.
If number of seconds not specified then it defaults to 1 second.
echo "$(date::sub_seconds "1")"
#Output
1591554425
Format unix timestamp to human readable format.
If format string is not specified then it defaults to “yyyy-mm-dd hhss” format.
date
command (optional).
echo echo "$(date::format "1594143480")"
#Output
2020-07-07 18:38:00
Functions to facilitate debugging scripts.
Prints the content of array as key value pair for easier debugging.
Pass the variable name of the array instead of value of the variable.
array=(foo bar baz)
printf "Array\n"
printarr "array"
declare -A assoc_array
assoc_array=([foo]=bar [baz]=foobar)
printf "Assoc Array\n"
printarr "assoc_array"
#Output
Array
0 = foo
1 = bar
2 = baz
Assoc Array
baz = foobar
foo = bar
Function to print ansi escape sequence as is.
This function helps debug ansi escape sequence in text by displaying the escape codes.
txt="$(tput bold)$(tput setaf 9)This is bold red text$(tput sgr0).$(tput setaf 10)This is green text$(tput sgr0)"
debug::print_ansi "$txt"
#Output
\e[1m\e[91mThis is bold red text\e(B\e[m.\e[92mThis is green text\e(B\e[m
Functions for handling files.
Create temporary file.
Function creates temporary file with random name. The temporary file will be deleted when script finishes.
Function has no arguments.
echo "$(file::make_temp_file)"
#Output
tmp.vgftzy
Create temporary directory.
Function creates temporary directory with random name. The temporary directory will be deleted when script finishes.
echo "$(utility::make_temp_dir)"
#Output
tmp.rtfsxy
Get only the filename from string path.
echo "$(file::name "/path/to/test.md")"
#Output
test.md
Get the basename of file from file name.
echo "$(file::basename "/path/to/test.md")"
#Output
test
Get the extension of file from file name.
echo "$(file::extension "/path/to/test.md")"
#Output
md
Get directory name from file path.
echo "$(file::dirname "/path/to/test.md")"
#Output
/path/to
Get absolute path of file or directory.
file::full_path "../path/to/file.md"
#Output
/home/labbots/docs/path/to/file.md
Get mime type of provided input.
file::mime_type "../src/file.sh"
#Output
application/x-shellscript
Search if a given pattern is found in file.
file::contains_text "./file.sh" "^[ @[:alpha:]]*"
file::contains_text "./file.sh" "@file"
#Output
0
Functions to format provided input.
Format seconds to human readable format.
echo "$(format::human_readable_seconds "356786")"
#Output
4 days 3 hours 6 minute(s) and 26 seconds
Format bytes to human readable format.
echo "$(format::bytes_to_human "2250")"
#Output
2.19 KB
Remove Ansi escape sequences from given text.
format::strip_ansi "\e[1m\e[91mThis is bold red text\e(B\e[m.\e[92mThis is green text.\e(B\e[m"
#Output
This is bold red text.This is green text.
Prints the given text to centre of terminal.
format::text_center "This text is in centre of the terminal." "-"
Format String to print beautiful report.
format::report "Initialising mission state" "Success"
#Output
Initialising mission state ....................................................................[ Success ]
Trim given text to width of the terminal window.
format::trim_text_to_term "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." "This is part of second sentence."
#Output
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod..This is part of second sentence.
Functions to enable interaction with the user.
Prompt yes or no question to the user.
interaction::prompt_yes_no "Are you sure to proceed" "yes"
#Output
Are you sure to proceed (y/n)? [y]
Prompt question to the user.
interaction::prompt_response "Choose directory to install" "/home/path"
#Output
Choose directory to install? [/home/path]
Simple json manipulation. These functions does not completely replace jq
in any way.
Extract value from json based on key and position.
Input to the function can be a pipe output, here-string or file.
json::get_value "id" "1" < json_file
json::get_value "id" <<< "${json_var}"
echo "{\"data\":{\"id\":\"123\",\"value\":\"name string\"}}" | json::get_value "id"
Set of miscellaneous helper functions.
Check if internet connection is available.
Function has no arguments.
misc::check_internet_connection
Get list of process ids based on process name.
misc::get_pid "chrome"
#Ouput
25951
26043
26528
26561
Get user id based on username.
misc::get_uid "labbots"
#Ouput
1000
Generate random uuid.
Function has no arguments.
misc::generate_uuid
#Ouput
65bc64d1-d355-4ffc-a9d9-dc4f3954c34c
Functions to detect Operating system and version.
Identify the OS the function is run on.
Function has no arguments.
os::detect_os
#Output
linux
Identify the distribution flavour of linux.
Function has no arguments.
os::detect_linux_distro
#Output
ubuntu
Identify the Linux version.
Function has no arguments.
os::detect_linux_version
#Output
20.04
Identify the MacOS version.
Function has no arguments.
os::detect_linux_version
#Output
10.15.7
Functions for string operations and manipulations.
Strip whitespace from the beginning and end of a string.
echo "$(string::trim " Hello World! ")"
#Output
Hello World!
Split a string to array by a delimiter.
array=( $(string::split "a,b,c" ",") )
printf "%s" "$(string::split "Hello!World" "!")"
#Output
Hello
World
Strip characters from the beginning of a string.
echo "$(string::lstrip "Hello World!" "He")"
#Output
llo World!
Strip characters from the end of a string.
echo "$(string::rstrip "Hello World!" "d!")"
#Output
Hello Worl
Make a string lowercase.
echo "$(string::to_lower "HellO")"
#Output
hello
Make a string all uppercase.
echo "$(string::to_upper "HellO")"
#Output
HELLO
Check whether the search string exists within the input string.
string::contains "Hello World!" "lo"
Check whether the input string starts with key string.
string::starts_with "Hello World!" "He"
Check whether the input string ends with key string.
string::ends_with "Hello World!" "d!"
Check whether the input string matches the given regex.
string::regex "HELLO" "^[A-Z]*$"
Set of useful terminal functions.
Check if script is run in terminal.
Function has no arguments.
Detect profile rc file for zsh and bash of current script running user.
Function has no arguments.
Clear the output in terminal on the specified line number.
This function clears line only on terminal.
Functions to perform validation on given data.
Validate whether a given input is a valid email address or not.
test='test@gmail.com'
validation::email "${test}"
echo $?
#Output
0
Validate whether a given input is a valid IP V4 address.
ips='
4.2.2.2
a.b.c.d
192.168.1.1
0.0.0.0
255.255.255.255
255.255.255.256
192.168.0.1
192.168.0
1234.123.123.123
0.192.168.1
'
for ip in $ips; do
if validation::ipv4 $ip; then stat='good'; else stat='bad'; fi
printf "%-20s: %s\n" "$ip" "$stat"
done
#Output
4.2.2.2 : good
a.b.c.d : bad
192.168.1.1 : good
0.0.0.0 : good
255.255.255.255 : good
255.255.255.256 : bad
192.168.0.1 : good
192.168.0 : bad
1234.123.123.123 : bad
0.192.168.1 : good
Validate whether a given input is a valid IP V6 address.
ips='
2001:db8:85a3:8d3:1319:8a2e:370:7348
fe80::1ff:fe23:4567:890a
fe80::1ff:fe23:4567:890a%eth2
2001:0db8:85a3:0000:0000:8a2e:0370:7334:foo:bar
fezy::1ff:fe23:4567:890a
::
2001:db8::
'
for ip in $ips; do
if validation::ipv6 $ip; then stat='good'; else stat='bad'; fi
printf "%-50s= %s\n" "$ip" "$stat"
done
#Output
2001:db8:85a3:8d3:1319:8a2e:370:7348 = good
fe80::1ff:fe23:4567:890a = good
fe80::1ff:fe23:4567:890a%eth2 = good
2001:0db8:85a3:0000:0000:8a2e:0370:7334:foo:bar = bad
fezy::1ff:fe23:4567:890a = bad
:: = good
2001:db8:: = good
Validate if given variable is entirely alphabetic characters.
test='abcABC'
validation::alpha "${test}"
echo $?
#Output
0
Check if given variable contains only alpha-numeric characters.
test='abc123'
validation::alpha_num "${test}"
echo $?
#Output
0
Validate if given variable contains only alpha-numeric characters, as well as dashes and underscores.
test='abc-ABC_cD'
validation::alpha_dash "${test}"
echo $?
#Output
0
Compares version numbers and provides return based on whether the value in equal, less than or greater.
test='abc-ABC_cD'
validation::version_comparison "12.0.1" "12.0.1"
echo $?
#Output
0
Functions for handling variables.
Check if given variable is array.
Pass the variable name instead of value of the variable.
arr=("a" "b" "c")
variable::is_array "arr"
#Output
0
Check if given variable is a number.
variable::is_numeric "1234"
#Output
0
Check if given variable is an integer.
variable::is_int "+1234"
#Output
0
Check if given variable is a float.
variable::is_float "+1234.0"
#Output
0
Check if given variable is a boolean.
variable::is_bool "true"
#Output
0
Check if given variable is a true.
variable::is_true "true"
#Output
0
Check if given variable is false.
variable::is_false "false"
#Output
0
Check if given variable is empty or null.
test=''
variable::is_empty_or_null $test
#Output
0