zerg-larva is a base shell script from which all other scripts and, ultimately, more complex components, can be created. Clone zerg-larva and mutate it into anything else.
Build any shell script, by duplicating/cloning the original source file.
It supports:
- CLI POSIX compliant arguments management
- Embedded default arguments/operations:
--verbose,--help,--version,--list-exit-codes - Easy logging
- Verbose mode
- Default function template
The script is divided into sections, listed below.
Used to define more strict Bash behaviour.
Modify only if required or for a specific purpose.
Modifiy the contents of this section to set up:
- Your Application Name
- Your Application Version
Modifiy the contents of this section to set up all the return codes used by your script.
RC_OK=0 and RC_UNKNOWN=125 should always been defined. Other codes are free to use, in the range 0–125.
This section is used to init default system values. Never modify any variable here.
This section lists all the arguments used by your script's command line. Their default values are set to FALSE or empty, so they are enabled during pattern detection.
The following block then allows the value of these variables to be modified according to a string of characters detected in the command line.
The arguments --help, --version, --verbose, and --list-exit-codes are default arguments and should always be retained.
The --directory argument shows how to capture a string and use it as the target directory for further processing.
This section defines the default functions made available by the script: z_log(), z_die(), z_help(), z_list_exit_codes(), z_trace(), z_checkdep(), and z_dump().
The content of this section must not be modified.
This section defines user-created functions. All business functions must be placed here. The get_timestamp() function is a placeholder used as an example.
Note regarding user functions:
- A function should always return 0 on success;
- A function should always return a number greater than 0 on error. This number must be a constant listed in the
Return Codessection. - A fatal error encountered during execution should always trigger
exit()or az_die()call.
This section contains the main program, built from user-defined functions.
This section calls main(), displays help, version number or a list of return codes.
- Clone source file from
gitor unpack the provided archive
asphyx@KERRIGAN:~/code$ git clone https://github.com/asphyx0r/zerg-larva.git ProjectName
asphyx@KERRIGAN:~/code$ cd ProjectName- Update script headers using Makefile:
asphyx@KERRIGAN:~/code$ make release- Duplicate and rename original file
zerg-larva.shto your target script:
asphyx@KERRIGAN:~/code$ mv ./zerg-larva.sh vxBackup.sh- Edit your new file with your favorite editor:
asphyx@KERRIGAN:~/code$ nano vxBackup.sh - Line 3 to Line 19 and beyond, document the script using the header template:
# Name : <script_name>.sh
# Description : Short description of the script purpose.
# Usage : script_name.sh [options]
# Author : Your Name - Your Email
# Version : v1.0.0
# Date : 2025-12-01
# License : MIT License
# Repository : https://github.com/yourname/script_name.git- Line 31, edit the value of the variable
APPNAMEto set your application human-readable name:
readonly APPNAME="ApplicationName"- Line 32, edit the value of the variable
VERSIONto set your application version number:
readonly VERSION="v1.0.0"- Line 49 to Line 59, list all the exit codes used by the script.
readonly RC_OK=0
readonly RC_MISSING_OPERAND=1
readonly RC_UNKNOWN_OPERAND=2
readonly RC_INTERNAL_LOG_ARGS=3
readonly RC_MISSING_DIRECTORY=4
readonly RC_INVALID_DIRECTORY=5
readonly RC_INTERNAL_DEP_ARGS=6
readonly RC_MISSING_PREREQ=7
readonly RC_INTERNAL_TRC_ARGS=8
readonly RC_INTERNAL_INT_ARGS=9
readonly RC_DUMMY_ERROR=124The free range is 0–125:
| Codes | Description |
|---|---|
| 0 | Success |
| 1-125 | Application errors (available for your script) |
| 126 | The command exists but cannot be executed |
| 127 | The command does not exist |
| 128+N | The command terminated due to signal N. Example: 130 = 128+2, SIGINT = 2 |
| Codes | Description |
|---|---|
| 126–127 | Reserved by POSIX for standard system error cases. |
| 128–255 | Reserved for signal terminations. |
- Line 65, define the default log level threshold:
LOG_LEVEL="${LOG_LEVEL:-INFO}"- Line 91 and later, assign a variable and a default value for each of your command line argument:
arg_help=false
arg_version=false
arg_verbose=false
arg_list_exit_codes=false
arg_directory=""- Line 107 and later, set the list of strings to be matched as arguments in the command line and assign it to the variables listed at step 8:
-h|--help)
arg_help=true
shift
;;
--version)
arg_version=true
shift
;;
-v|--verbose)
arg_verbose=true
shift
;;
--list-exit-codes)
arg_list_exit_codes=true
shift
;;
-d|--directory)Some arguments can handle a second keyword. See --directory as example.
The string has to be defined but not be an argument by itself:
if [[ -z "$arg_directory" || $arg_directory == "--"* || $arg_directory == "-"* ]] ; then
echo "Missing DIRECTORY" >&2;
echo "Try '$script_name --help' for more information.";
RC=4
exit $RC
fi
# DIRECTORY is followed by a directory string so shift 2
shift 2
;;- Print the script exit codes (no side effects):
zerg-larva.sh --list-exit-codes- Run the script verbosely against a directory (must exist):
zerg-larva.sh --verbose -d /path/to/existing/directoryNotes:
--list-exit-codeswill print the RC mapping and exit 0.- The script requires at least one argument; calling it with no args returns RC=1.
NAME
z_log() - Print a log line on STDOUT (DEBUG/INFO), or STDERR (WARN/ERROR/FATAL)
SYNOPSIS
z_log <LEVEL> <MESSAGE>
DESCRIPTION
Displays the MESSAGE preceded by a timestamp and the LEVEL of the event.
Level can be (FATAL|ERROR|WARN|INFO|DEBUG).
Messages below threshold defined by the global variable LOG_LEVEL won't be displayed.
(can be overridden by env: LOG_LEVEL=DEBUG ./script.sh ...)
WARN messages and above are routed to STDERR:
./zerg-larva.sh -d /home/asphyx/ >out.log 2>err.log
Output pattern: YYYY-MM-DD HH:MM:SS [LEVEL] - func(line): message
[LEVEL] will always be truncated to 5 caracters.
EXIT STATUS
3 RC_INTERNAL_LOG_ARGS: Wrong number of arguments.
OUTPUT
<LEVEL TIMESTAMP - FUNCTION: LOG LINE
NAME
z_help() - Display help and script usage information
SYNOPSIS
z_help
DESCRIPTION
Displays the script usage information on STDOUT.
Modify the formatted block to fit you script arguments.
This block should contain all the arguments listed in the ARGUMENTS section,
declared at the beginning of the script via appropriate variables.
EXIT STATUS
0
OUTPUT
Contents of <<-EOF ... EOF block
NAME
z_list_exit_codes() - Display script exit codes information
SYNOPSIS
z_list_exit_codes
DESCRIPTION
List all script exit codes on STDOUT.
Modify the formatted block to fit you script arguments.
This block should contain all the codes listed in the
RETURN CODES section, declared at the beginning of the script via constants.
EXIT STATUS
0
OUTPUT
Contents of <<-EOF ... EOF block
NAME
z_trace() - Enable 'set -x' tracing for debugging purpose
SYNOPSIS
z_trace BOOLEAN
0 | off | false : Disable tracing
1 | on | true : Enable tracing
DESCRIPTION
Enable 'set -x' for local debugging.
Your tracked code block should be enclosed between two z_tracecalls:
z_trace 1
<...>
z_trace 0
EXIT STATUS
0 : Success
RC_INTERNAL_TRC_ARGS if called with wrong number of arguments (1 expected)
RC_INTERNAL_TRC_ARGS if called invalid argument (Boolean expected)
OUTPUT
Bash debugging information
NAME
z_die() - Display error message then exit with return code
SYNOPSIS
z_die <EXIT_CODE> <MESSAGE>
DESCRIPTION
Display the MESSAGE on STDOUT (error message)
Exits with the provided EXIT_CODE (Return RC_UNKNOWN if non-numeric code used)
Display stacktrace if --verbose mode enabled
EXIT STATUS
<EXIT_CODE>
OUTPUT
ERROR <MESSAGE>
NAME
z_checkdep() - Verify if required command is available.
SYNOPSIS
z_checkdep <COMMAND>
DESCRIPTION
Check if the given command exists in PATH.
Return true if the dependency is found, false otherwise.
EXIT STATUS
6 RC_INTERNAL_DEP_ARGS: Wrong number of arguments.
Calling the function with a wrong number of arguments will exit().
(Being unable to check dependencies is a fatal error)
Example:
export sampleCommand="bash"
if ! z_checkdep "$sampleCommand"; then
z_die "$RC_MISSING_PREREQ" "A required dependency '$sampleCommand' is missing, cannot continue."
fiOUTPUT
Search result as DEBUG message (using z_log function)
NAME
z_dump() - Print debug information
SYNOPSIS
z_dump
DESCRIPTION
Print debug information about the script (name, path, full path, arguments, system variables).
The z_log() function is used to output the system variables.
Active only if the --verbose argument is passed on the command line AND if log level is set to DEBUG
EXIT STATUS
0
OUTPUT
script start date
script start time
script PID
script PPID
script full path
script directory
script name
script path
arguments
user
hostname
bash version
NAME
z_stacktrace() - Generate stack trace for debugging purpose
SYNOPSIS
z_stacktrace
DESCRIPTION
Display stack trace to STDOUT.
Show parent function, script name and line number.
Active only if the --verbose argument is passed on the command line
EXIT STATUS
0
OUTPUT
Formatted stack trace:
Stack trace:
↳ f3 (zerg-larva.sh:448)
↳ f2 (zerg-larva.sh:449)
↳ f1 (zerg-larva.sh:450)
↳ main (zerg-larva.sh:451)
↳ main (zerg-larva.sh:484)
NAME
z_trap_exit() - Basic EXIT trap
SYNOPSIS
trap 'z_trap_exit' EXIT
DESCRIPTION
This code snippet can be called when trapping an EXIT event.
Show script return code, date and time of completion then duration.
EXIT STATUS
Return the latest script RC
OUTPUT
Info log line:
[INFO] 2025-12-23 17:32:03 - z_trap_exit(462): Exiting (RC=0), End: 2025-12-23 17:32:03, Duration: 0s
NAME
z_trap_error() - Basic ERR trap
SYNOPSIS
trap 'z_trap_error' ERR
DESCRIPTION
This code snippet can be called when trapping an ERROR event.
Show The latest error code, and the command/function which failed.
EXIT STATUS
Return the latest command error code
OUTPUT
Info log line:
[ERROR] 2025-12-23 19:13:03 - z_trap_error(487): Command failed (rc=1) at ./zerg-larva.sh:625 in run_case(): "$@"
Stack trace:
↳ z_trap_error (zerg-larva.sh:487)
↳ run_case (zerg-larva.sh:625)
↳ main (zerg-larva.sh:635)
↳ main (zerg-larva.sh:664)
NAME
get_timestamp() - Return a timestamp string
SYNOPSIS
get_timestamp
DESCRIPTION
Return a compact timestamp string.
This function is a sample function to be used as template/skeleton
The purpose is to populate the User Functions script section.
EXIT STATUS
0
OUTPUT
Timestamp string (YYYYmmdd-HHMMSS)
NAME
dummy_function() - Do nothing
SYNOPSIS
dummy_function
DESCRIPTION
Do nothing.
This function is a sample function to be used as template/skeleton
The purpose is to populate the User Functions script section.
EXIT STATUS
0
124 RC_DUMMY_ERROR: Wrong number of arguments.
OUTPUT
Nothing
NAME
main() - Run the program
SYNOPSIS
main
DESCRIPTION
Primary driver.
Logs start/end, optionally dumps debug info if verbose, demonstrates logging and exits with $RC.
Your custom code must be called inside the main() function.
Replace the content of the main()function with your Business Logic Functions.
Change the value of $RC to handle errors and exit properly.
EXIT STATUS
Return with the current value of $RC (default 0 unless changed earlier).
OUTPUT
None
This script is provided with the following default exit codes. This codes can be changed, or new one can be added. The free range is 0–125:
- 0 — Success / default (no error)
- 1 — Missing operand (no arguments provided)
- 2 — Unknown operand (invalid option passed)
- 3 — Internal error:
z_log()called with wrong number of arguments - 4 — Missing DIRECTORY for
-d|--directoryoption (directory argument not provided or invalid) - 5 — Provided DIRECTORY does not exist or is not accessible
- 6 — Internal error:
z_checkdep()called with wrong number of arguments - 7 — Missing prerequisite (required command not found)
- 8 — Internal error:
z_trace()called with wrong number of arguments - 124 — Dummy error for demonstration purposes
- 125 — Unknown error
This script requires the following external programs and shell features:
- bash(1)
- Used as the script interpreter (shebang
#!/usr/bin/env bash). The script uses Bash-specific features such as[[ ... ]],local, andfunction.
- Used as the script interpreter (shebang
- date(1)
- Used to generate timestamps in
z_log()andget_timestamp()(format strings via+FORMAT).
- Used to generate timestamps in
- Conditional expressions
[[ ... ]]and file tests-d,-r,-x. case/shiftargument parsing.localvariables inside functions.- Here-documents (
cat <<-EOF) for help and exit-code printing. - Parameter expansions
${0##*/},${@},${0%/*}and command substitution$(...).
- The script checks directories for existence and read/execute permissions; it assumes a POSIX-like filesystem and permission model.
- Invoke with
bash zerg-larva.shor ensure the file is executable and the shebang is respected (chmod +x zerg-larva.sh).
This script is provided by these default command line options.
Modify the content of the z_help() function to fit your needs:
Usage: zerg-larva.sh [OPTION]
-d, --directory DIRECTORY set directory to work on
-v, --verbose print debugging information
-h, --help display this help and exit
--version output version information and exit
--list-exit-codes print the list of script exit codes and exit
- ba703ae 2025-12-29 Added Makefile to update token in script header
- 43fd78e 2025-12-29 Updated README.md to reflect z_log STDERR behavior for WARN, ERROR, FATAL
- ddd0f9b 2025-12-29 z_log() headers updated to match stderr routing
- 3581926 2025-12-29 z_list_exit_codes(): added RC_INTERNAL_INT_ARGS=9
- 2159d40 2025-12-29 "echo -e" removal
- ef217d1 2025-12-29 Removed noise in z_dump function
- a76bbe3 2025-12-27 z_stacktrace(): No WARN noise without --verbose
- 7e226aa 2025-12-27 z_log(): Invalid level fallback message to stderr
- 0a6288a 2025-12-27 Validate allowed levels before threshold
- 496d02d 2025-12-27 z_log(): sanitize log level input
- 7ac67d9 2025-12-27 Arm
trap 'z_trap_exit' EXIT`trap 'z_trap_error' - bb54eb6 2025-12-27 main made non-zero compatible with
set -e
- 170ccd4 2025-12-24 Fixed target directory validation logic
- bd404d8 2025-12-24 Added --verbose to z_stacktrace() description
- 59a2ebd 2025-12-24 README improvements and useless variable removal
- 6fdd15d 2025-12-24 Updated README.md to reflect z_log() changes
- 2a2212b 2025-12-24 STDOUT/STDERR filtering based on level in z_log()
- 8257e56 2025-12-24 Allow multiples arguments as message in z_log()
- 78de3bf 2025-12-24 Improvement to the z_log() function
- bc68d4e 2025-12-24 Improvement to the z_trace() function
- 326d685 2025-12-24 Updated z_die() entry in README.md
- 42d220f 2025-12-24 Improvement to the z_die() function
- accba42 2025-12-24 z_log() returns RC_INTERNAL_LOG_ARGS on wrong args
- 5878068 2025-12-23 Added z_trap_error() to catch ERR events
- b65cef3 2025-12-23 Added trap to log exit info on script termination
- 5d25adf 2025-12-23 z_stacktrace() only available in verbose mode
- 2c62f16 2025-12-23 Standardized CLI behavior: handle no args cleanly
- bdf3fd8 2025-12-23 Fixed catching of main() return code
- 7b2f5c7 2025-12-23 Application Name and Version replaced by tokens
- 53e1905 2025-12-23 Replacing metadata examples with tokens
- 5f02bbb 2025-12-23 Fixed gloabl variable "sample_command" in main()
- a1a6107 2025-12-23 Fixed z_dump() behaviour
- aa327e0 2025-12-23 Fixed return logic in z_checkdep()
- 629ee28 2025-12-23 Added n var. to the local z_stacktrace() namespace
- 64ac794 2025-12-23 Using printf instead of echo to avoid escape issue
- 684e1cc 2025-12-22 ZRGLRV-0003 Variables names switched to snake_case
- e3073fd 2025-12-22 ZRGLRV-0003 Variables names switched to snake_case
- 6d5f094 2025-12-22 Added dummy_function() as template example
- 2ef1dde 2025-12-22 Added custom .editorconfig file to .gitignore
- ce9e8d9 2025-12-22 Updated .gitignore with more temp files
- a49aa06 2025-12-18 Fixed wrong function names in documentation
- 01e843d 2025-12-18 Updated FILE_ID.DIZ with tag number v1.0.10
- edebbc1 2025-12-18 Added FILE_ID.DIZ for BBS distribution
- 6cad6f0 2025-12-18 Added ZERG.NFO file to project root
- 9c7e83c 2025-12-17 Internal functions renamed with "z_" prefix
- 6c67c2f 2025-12-17 getTimestamp() renamed to get_timestamp()
- 3a4f047 2025-12-17 Added .vscode to .gitignore
- 50f036b 2025-12-16 Updated .gitignore to include TODO.md
- 200b12b 2025-12-16 Fixed missing section separator in README.md/trace
- 3c3e2b9 2025-12-16 Shellcheck disabled for inused RC_UNKNOWN
- 488f3d9 2025-12-16 Renamed README.MD to README.md for consistency
- 41ccb95 2025-12-16 Global variable $RC set to EXIT CODE in die()
- 05d54fb 2025-12-08 CHANGELOG.md Update
- 82f56b7 2025-12-08 CHANGELOG.md Update
- f431d73 2025-12-08 Added stacktrace() function
- f6a26a8 2025-12-08 Fixed the reversal of return codes in checkdep()
- 785377c 2025-12-08 log(): Being unable to log is not a fatal error
- 934c012 2025-12-08 dump() function improvements
- fc448cb 2025-12-08 Updated README: new behavior of the log() function
- 2fa629d 2025-12-08 Log() function improvement
- 6313428 2025-12-08 Added line number tracking in trace() function
- f80fc25 2025-12-07 Documentation improvement
- 0f35450 2025-12-07 Documentation improvement
- da96409 2025-12-07 Fixed typo in main() comment
- d4d0075 2025-12-07 Correction of the function return method
- b85cafe 2025-12-07 Added trace() function
- 72c14d0 2025-12-07 Added help() and list_exit_codes() functions
- c7ecbda 2025-12-06 Added die() and checkdep() functions
- 80ecf69 2025-12-06 Added die() and checkdep() functions
- ad08470 2025-12-06 Added man section for main() function
- 930a638 2025-12-06 Added man section for main() function
- cd059ad 2025-12-06 Added man section for getTimestamp() function
- 2c72c41 2025-12-06 Added man section for dump() function
- e71dd2a 2025-12-06 Added man section for log() function
- 50b3b37 2025-12-06 Adding Bash docstrings to functions
- 293298e 2025-12-06 Fixed typo in RC list
- a966baf 2025-12-06 Improvements to the script structure and comments
- dd3c28d 2025-12-06 Update CHANGELOG/README for v1.0.5
- f2a748b 2025-12-06 Update CHANGELOG/README for v1.0.5
- 4281261 2025-12-06 Added tools used to generate CHANGELOG
- 4d6d9a9 2025-12-06 Update CHANGELOG for v1.0.4
- 99f8474 2025-12-06 Update CHANGELOG for v1.0.4
- 1e0c5fd 2025-11-30 Updated changelog with v1.0.3 commits
- 66cc2b2 2025-11-30 Return codes documentation
- 8d1bad3 2025-11-29 Improved return code management in zerg-larva.sh
- 3992a05 2025-11-29 Fixed wrong line break in README.MD
- f655366 2025-11-29 Updated .gitignore to exclude more files
- d707968 2025-11-27 Git customization
v1.0.2 - Update README and script metadata for clarity and consistency, improved security fixes (2025-11-24)
- c5ffbf3 2025-11-22 Update README and script metadata for clarity and consistency, improved security fixes
- c8135a4 2025-11-21 Add safety settings to improve script robustness
- 5fadc91 2025-11-21 Enhance script header with detailed metadata and prerequisites
- 7c75b01 2025-11-08 Added Git default files
- 3bf9436 2025-11-08 Repo init: first commit
- GitHub Home: https://github.com/asphyx0r/zerg-larva
- GitHub Repository: https://github.com/asphyx0r/zerg-larva.git
- Latests Release: https://github.com/asphyx0r/zerg-larva/releases/latest/