A collection of (mostly) POSIX-compliant functions to extend Bourne-Shell (sh) functionality.
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
Table of Contents
After developing several shell scripts it was time to gather recurring code patterns and store them in a library. The goal of this project is to provide a (mostly) POSIX-/Bourne-Shell(sh)-compliant library that provides
-
essential functions, such as
- checking the existence of a command/directory/file,
- performing regular expression checks,
- converting/modifying variables,
- string manipulation,
-
mathematical functions and operations, such as
- advanced calculation using
bc
(supporting floating point numbers), - converting units, e.g. from 'MB' into 'GB',
- checking if a number is within a specified range,
- functions like
abs
orsign
,
- advanced calculation using
-
logging and output formatting functions, such as
- system logging,
- formatting terminal messages,
- providing message templates, e.g. license notification,
-
network related functions, such as
- changing an interface's IP address,
- retrieving interface statistics,
- creating/removing bridges,
- performing DNS lookups,
-
OS-related functions, such as
- retrieving CPU/RAM information,
- process-related tasks,
- modifying bootloader settings, or
- SSH/SCP wrapper,
-
special tool-related functions, e.g. for
- iperf3,
- NetworkManager,
- OpenWRT,
- Tcpdump,
-
and much more.
The project has been developed and tested on the following system:
Info | Description |
---|---|
OS | Debian GNU/Linux 12 (bookworm) |
Kernel | 5.15.133.1-microsoft-standard-WSL2 |
Packages | bc (1.07.1-3+b1) |
bind9-dnsutils (1:9.18.19-1~deb12u1) | |
coreutils (9.1-1) | |
dash (0.5.12-2) | |
dialog (1.3-20230209-1) | |
iproute2 (6.1.0-3) | |
libc-bin (2.36-9+deb12u3) | |
netcat (1.10-46) | |
network-manager (1.42.4-1) | |
sudo (1.9.13p3-1+deb12u1) | |
udev (252.19-1~deb12u1) |
ℹ️ Most of the packages are optional and only needed for certain library functions.
Please make sure that the following dependencies are installed:
- POSIX-/Bourne-compliant shell
- Additional packages (only needed for certain functions, see Testing Environment)
Below you can find distribution-specific installation instructions (only needed for additional packages).
apk add bc bind-tools coreutils dialog iproute2 netcat-openbsd networkmanager-cli sudo
apt install bc bind9-dnsutils coreutils dash dialog iproute2 libc-bin netcat network-manager sudo udev
-
Change into the root folder of a (local) repo that will use the library.
-
Add this repo as a submodule:
git submodule add https://github.com/fkemser/SHlib lib/SHlib
-
To source (use) the library within your project simply put the following code at the beginning of your script:
# Get current working direcotry readonly CWD="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" # Change to library directory # TODO: Adapt the path according to your repository structure cd "${CWD}/../lib/SHlib" >/dev/null 2>&1 || return # Source libraries for lib in ./*.lib.sh; do . "${lib}" || \ { printf "%s\n\n" \ "ERROR: Library '$lib' could not be loaded. Aborting..." >&2 cd "${CWD}" return 1 } done # Restore original directory cd "${CWD}"
⚠️ The following sections only give a brief overview. Before running any of these functions please have a look at the comments in the source files.
The library is separated in several files where each file stores a certain category of functions and/or constants:
File (/lib/...) | Description |
---|---|
c.lib.sh |
Constants used by other library files and shell projects |
core.lib.sh |
Essential functions, e.g. type/regex checks, variable manipulation, etc. |
iperf3.lib.sh |
iperf3 -related functions |
math.lib.sh |
Mathematical functions and operations |
msg.lib.sh |
Logging and output formatting functions |
net.lib.sh |
Network-related functions |
nm.lib.sh |
nmcli -related functions (NetworkManager) |
openwrt.lib.sh |
OpenWRT -related functions |
os.lib.sh |
OS-related functions |
tcpdump.lib.sh |
tcpdump -related functions |
This file contains constans that are used by other library files and/or other projects, e.g.
- Linux distribution IDs,
- language IDs (ISO 639-1),
- further text constants.
Function | Description |
---|---|
lib_core_args_passed |
Check if at least one argument has been passed |
lib_core_bool2int |
Convert one or more boolean values to integer values |
lib_core_can_sudo_nopasswd |
Check if current user can sudo without password prompt |
lib_core_char_repeat |
Repeat a given character for a certain number of times |
lib_core_cmd_exists |
Check if (one or more) commands exist on the host |
lib_core_cmd_exists_su |
Check if (one or more) commands exist when using root |
lib_core_echo |
Print a message |
lib_core_env_append |
Append one or more values to an environment variable |
lib_core_env_remove |
Remove one or more values from an environment variable |
lib_core_expand_tilde |
Expand '~' to the user's home directory '$HOME' in a given path |
lib_core_file_get |
Get file information |
lib_core_file_touch |
Create one or more files and (if needed) their parent folders |
lib_core_float2int |
Convert one or more floating point numbers to integer |
lib_core_int_is_within_range |
Check if an integer number is between a given range. This function is only intended for integer numbers. To process floating point numbers please use lib_math_is_within_range . |
lib_core_int_max |
Return maximum of a list of integer values |
lib_core_int_min |
Return minimum of a list of integer values |
lib_core_is |
Perform checks on current environment (root, interactive shell, etc.) and arguments (bool, file, integer, etc.) |
lib_core_list_contains_str |
Looks for a string within a delimited list of strings |
lib_core_list_contains_str_ptr |
Looks for a string within a delimited list of strings where the list does not(!) contain the strings themselves but their variable pointers |
lib_core_parse_credentials |
Parse credentials that are provided via an environment variable |
lib_core_path_get_abs |
Get absolute path to a directory or file (in case it contains relative paths or symlinks) |
lib_core_regex |
Check if a given string matches a regular expression |
lib_core_str_get_length |
Get length of a string |
lib_core_str_filter_and_sort |
Filter and sort a (multiline) string |
lib_core_str_get_substr |
Extract a substring from a given string |
lib_core_str_is_multiline |
Check if one or more strings contain more than one line |
lib_core_str_random |
Generate a random string |
lib_core_str_remove_leading |
Remove leading character(s) from one or multiple string(s) |
lib_core_str_remove_newline |
Replace line breaks from a string by a certain character |
lib_core_str_remove_trailing |
Remove trailing character(s) from one or multiple string(s) |
lib_core_str_replace_char |
Replace (or delete) all occurrences of a character in a string by using tr command. |
lib_core_str_replace_substr |
Replace (or delete) all occurrences of a substring in a string by using sed command. |
lib_core_str_split |
Split a given string into substrings (separated by <newline> ) but preserve quoted ("..." ) substrings even if they contain spaces |
lib_core_str_to |
Convert one or multiple string(s) |
lib_core_sudo |
Execute one or more commands with root privileges |
lib_core_sudo_background |
Execute one or more commands with root privileges and put them into background |
lib_core_sysfs_get |
Wrapper for accessing sysfs |
lib_core_time_timestamp |
Get current time in UNIX Epoch format |
lib_core_var_is |
Perform general checks (defined, null, etc.) and type checks (bool, file, integer, etc.) on variables. Similar to lib_core_is but expects identifiers (var1 var2 ... ) instead of values ($var1 $var2 ... ). |
Function | Description |
---|---|
lib_iperf3_log_parse_transfer_rate |
Extract transfer rate from an ipferf3 log |
Function | Description |
---|---|
lib_math_abs |
Calculate absolute value of one or more given values (abs(x) ) |
lib_math_calc |
Perform a calculation supporting decimal places by using bc |
lib_math_convert_unit |
Convert a given value (integer/float) from one unit to another |
lib_math_is_within_range |
Check if an (integer or float) number is between a given range |
lib_math_is_within_range_u |
Like lib_math_is_within_range but with units |
lib_math_sign |
Get sign of one or more given values (sign(x) ) |
Function | Description |
---|---|
lib_msg_dialog_autosize |
Calculate the size of dialog boxes (see man dialog ) |
lib_msg_echo |
Print error/info/warning message to stdout /stderr |
lib_msg_log |
Log error/info/warning message to syslog |
lib_msg_message |
Log/Print error/info/warning message and optionally exit |
lib_msg_print_borderstring |
Print a string surrounded by border characters |
lib_msg_print_heading |
Format a string as a heading |
lib_msg_print_list |
Format and print values from a list |
lib_msg_print_propvalue |
Print a formatted table of property/value pairs to stdout |
lib_msg_term_get |
Get current terminal window's settings |
Function | Description |
---|---|
lib_net_bridge_create |
Create a network bridge and attach one or more physical interfaces to it |
lib_net_bridge_get_members |
Get network bridge members |
lib_net_bridge_remove |
Remove a network bridge |
lib_net_dns_resolve |
Resolve a given hostname, FQDN, SRV record, into IP address(es) (automatically detect the type of the input string) |
lib_net_host_is_up |
Check if a host is reachable on a given port |
lib_net_iface_get_sysfs / lib_net_iface_get_sysfs_statistics |
Get information about network interface using Linux kernel's / |
lib_net_iface_get_ip |
Get the current IP address of a network interface |
lib_net_iface_get_master |
Get master bridge that a (slave) device is attached to |
lib_net_iface_ip |
Add/Remove an IP address to/from a network device |
lib_net_iface_is |
Checks if one or interfaces are in a certain state (up |
lib_net_ifconfig_parse_stats |
Parse output |
Function | Description |
---|---|
lib_nm_con_exists |
Check if a a connection exists and optionally check if it's active |
lib_nm_con_get |
Get a certain connection setting/property |
lib_nm_con_list |
List connections (optionally filtered) |
lib_nm_con_modify |
Modify a certain connection setting/property |
Function | Description |
---|---|
lib_openwrt_procd_install |
Install and optionally enable/start procd init service |
Function | Description |
---|---|
lib_os_cgroup_parse_cpuacct |
Parse cgroup CPU accounting controller statistics |
lib_os_cgroup_parse_mem |
Parse cgroup memory statistics |
lib_os_boot_configure |
Modify bootloader settings |
lib_os_boot_configure_grub |
Modify "GRUB_CMDLINE_LINUX_DEFAULT" in GRUB settings |
lib_os_cpu_get |
Get CPU statistics |
lib_os_cpu_has_feature |
Check if (all) installed CPU(s) support(s) a given feature |
lib_os_dev_bus_usb_list |
List all currently connected USB devices with their corresponding device path (/dev/... ), their manufacturer and their product name |
lib_os_dev_bus_usb_list_by_busdev |
List device paths (/dev/... ) of USB devices matching (one or more) given bus and device numbers |
lib_os_dev_bus_usb_list_by_vidpid |
List device paths (/dev/... ) of USB devices matching (one or more) given vendor and/or product IDs |
lib_os_dev_class_list |
List device paths (/dev/... ) and corresponding IDs/names of a certain class |
lib_os_dev_is_mounted |
Check if (one or more) block devices are mounted |
lib_os_dev_umount |
Unmount (one or more) block devices including slave devices |
lib_os_dev_lsblk |
Get information about (one or more) block device using lsblk |
lib_os_get |
Get statistics about current distribution (ID, version, etc.) |
lib_os_is_subshell |
Check if the function that calls this function is running in a subshell |
lib_os_lib |
Check existence or get absolute path of a given library (.so) file |
lib_os_proc_meminfo |
Get memory statistics |
lib_os_ps_exists |
Check if a process with a given PID exists |
lib_os_ps_get_descendants |
Look for sub-processes |
lib_os_ps_get_mem |
Retrieve a process's memory (RAM) usage |
lib_os_ps_get_ownpid |
Get current shell's process ID |
lib_os_ps_get_pid |
Retrieve process ID(s) from a process defined via its name |
lib_os_ps_kill_by_name |
Kill a process by its name |
lib_os_ps_kill_by_pid |
Kill one or several processes by their PIDs |
lib_os_ps_kill_by_pidfile |
Kill a process by a PID file |
lib_os_ps_pidlock |
Enable a script to lock itself (prevent further instances) by using a PID file |
lib_os_scp_no_host_key_check |
SCP wrapper (SSH's host key binding check disabled) |
lib_os_ssh_no_host_key_check |
SSH command wrapper (SSH's host key binding check disabled) |
lib_os_ssh_test |
Check if one or more hosts are accessible via SSH (batch mode) |
lib_os_ssh_wrapper |
SSH command wrapper |
lib_os_user_is_member_of |
Check if current (or another) user is a member of a certain group |
Function | Description |
---|---|
lib_tcpdump_parse_logfile |
Parse tcpdump logfile |
See the open issues for a full list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the GNU Lesser General Public License v3.0 (or later). See LICENSE
for more information.
Project Link: https://github.com/fkemser/SHlib