A collection of useful scripts for various Linux distributions
This project can be installed as a Python package directly from GitHub, providing access to some Python libraries.
pip install git+https://github.com/eVAL-Agency/ScriptsCollection.gitFor development/editable installation:
git clone https://github.com/eVAL-Agency/ScriptsCollection.git
cd ScriptsCollection
pip install -e .Will compile each script into a single distributable file with all dependencies included within.
python3 compile.pyMost of the metadata is collected from the file header.
To ensure rendering, please ensure all file headers start with # ,
and separating lines contain a #.
Header scanning will stop as soon as an empty line is encountered.
Example, this will not see the "Supports" section as a header field, and thus will not include it.
#!/bin/bash
#
# Some title
# Supports:
# Debian 12Correct form includes a '#' to ensure the entire block is seen as the file header.
#!/bin/bash
#
# Some title
#
# Supports:
# Debian 12The first non-empty line retrieved from the script will be used as the title, (one line only).
Lists how to run the application to the end user, and gets saved in the help icon in TRMM.
#/bin/bash
# ...
# Syntax:
# --option1 - Short description of option 1
# --option2=... - Short description of option 2#!/usr/bin/env python3
"""
...
Syntax:
--option1 - Short description of option 1
--option2=... - Short description of option 2
"""Adding # compile:argparse to the script will generate a dynamic argument parser for the script.
(BASH only) Optionally, you can include the destination variable name before each argument
to allow for dynamic generation of the argument parsing via compile:argparse.
In this example, passing --noninteractive will set the variable NONINTERACTIVE to 1.
(The compiler will filter out the prefix)
#/bin/bash
# ...
# Syntax:
# NONINTERACTIVE=--noninteractive - Run in non-interactive mode, (will not ask for prompts)
# VERSION=--version=... - Version of Zabbix to install DEFAULT=7.0
# ZABBIX_SERVER=--server=... - Hostname or IP of Zabbix server
# ZABBIX_AGENT_HOSTNAME=--hostname=... - Hostname of local device for matching with a Zabbix host entry
# ...
# compile:argparseGenerates:
#/bin/bash
# ...
# Syntax:
# --noninteractive - Run in non-interactive mode, (will not ask for prompts)
# --version=... - Version of Zabbix to install DEFAULT=7.0
# --server=... - Hostname or IP of Zabbix server
# --hostname=... - Hostname of local device for matching with a Zabbix host entry
# ...
# Parse arguments
NONINTERACTIVE="0"
VERSION="7.0"
ZABBIX_SERVER=""
ZABBIX_AGENT_HOSTNAME=""
while [ "$#" -gt 0 ]; do
case "$1" in
--noninteractive) NONINTERACTIVE=1; shift 1;;
--version=*) VERSION="${1#*=}"; shift 1;;
--server=*) ZABBIX_SERVER="${1#*=}"; shift 1;;
--hostname=*) ZABBIX_AGENT_HOSTNAME="${1#*=}"; shift 1;;
-h|--help) usage;;
esac
done
if [ -z "$SOURCE" ]; then
usage
fi#!/usr/bin/env python3
"""
Do something
Syntax:
--arg1=<str> - Some parameter DEFAULT=yup
--arg2=<int> - The SSH key to authorize DEFAULT=42
"""
import argparse
# ...
parser = argparse.ArgumentParser(
prog='scriptname.py',
description='Does a thing')
# compile:argparse
args = parser.parse_args()To support Python, ensure a variable type is specified, like so:
#!/usr/bin/env python3
"""
Syntax:
--option1=<str> - Short description of option 1
--option2=<int> - Short description of option 2
"""Argument types in Bash are ignored and are for reference only.
The default value can be specified by appending DEFAULT=(value) to the argument, like so:
#/bin/bash
# ...
# Syntax:
# --option1=<str> - Short description of option 1 DEFAULT=default_value
# --option2=<int> - Short description of option 2 DEFAULT=42Lists the default arguments and their values to be used when running the script in TRMM.
DOES support TRMM variable replacement for site, client, and agent.
To use these, wrap the variable in double curly braces, like so: {{client.zabbix_hostname}}
#/bin/bash
# ...
# TRMM Arguments:
# --option1
# --option2=something#!/usr/bin/env python3
"""
...
Syntax:
--option1 - Short description of option 1
--option2=... - Short description of option 2
"""Behaves the same as TRMM Arguments, but is used for environment variables.
#/bin/bash
# ...
# TRMM Environment:
# VAR1=something
# VAR2={{client.zabbix_hostname}}#!/usr/bin/env python3
"""
...
TRMM Environment:
VAR1=something
VAR2={{client.zabbix_hostname}}
"""Lists the OS support for the script.
#/bin/bash
# ...
# Supports:
# Debian 12
# Ubuntu 24.04#!/usr/bin/env python3
"""
...
Supports:
Debian 12
Ubuntu 24.04
"""Distros can be listed individually, or one of the group declarations for multiple distros.
- Linux-All - All Linux-based distros (completely os-agnostic script)
- Debian-All - Any Debian-based distro (Debian, Ubuntu, Mint, etc)
- RHEL-All - Any Red Hat-based distro (RHEL, CentOS, Fedora, etc)
- ArchLinux / arch
- CentOS
- Debian
- Fedora
- LinuxMint
- RedHat / RHEL
- Rocky / RockyLinux
- SuSE / OpenSuSE
- Ubuntu
- Windows
#/bin/bash
# ...
# Author:
# Some Name <some-email@domain.tld>alternative syntax:
#/bin/bash
# ...
# @AUTHOR Some Name <some-email@domain.tld>#!/usr/bin/env python3
"""
...
@AUTHOR Some Name <some-email@domain.tld>
"""#/bin/bash
# ...
# Category:
# Some Categoryalternative syntax:
#/bin/bash
# ...
# @CATEGORY Some Category#!/usr/bin/env python3
"""
...
Category:
Some Category
"""#/bin/bash
# ...
# @TRMM-TIMEOUT 120#!/usr/bin/env python3
"""
...
@TRMM-TIMEOUT 120
"""Set to true to skip finalizing of the script. The script will still be generated to dist/, but will not be recorded in the README and TRMM metafile.
#/bin/bash
# ...
# Draft:
# True#!/usr/bin/env python3
"""
...
Draft:
True
"""The compiler can generate dynamic code based on script comments, notably for usage and arguments
Will generate a "usage()" function with the description and syntax arguments.
# compile:usageScriptlets are small pieces of reusable code that can be included in scripts during compilation.
This system provides a number of scripts, and more can be added by adding a compile.sources file in the root of the project
with the format:
scriptlet_type=github:repo_owner/repo_name
Where scriptlet_type is the directory that contains the scriptlets to include.
By default main is used to download sources, but a different branch can be specified by appending :branch_name.
To include this scriptlet:
# scriptlet:ufw/install.shInstall UFW
To include this scriptlet:
# scriptlet:io_github_lsferreira42/lib_ini.shPrint debug messages
Print error messages
Validate section name
Validate key name
Create a secure temporary file
Trim whitespace from start and end of a string
Escape special characters in a string for regex matching
To include this scriptlet:
# scriptlet:openjdk/install.shInstall OpenJDK from Eclipse Adoptium
@arg $1 string OpenJDK version to install
Will print the directory where OpenJDK was installed.
CHANGELOG: 2026.01.13 - Initial version
To include this scriptlet:
# scriptlet:steam/install-steamcmd.shInstall SteamCMD
CHANGELOG:
2025.12.16 - Ensure steam GPG key is readable by apt 2025.11.09 - Switch to using download to support curl/wget abstraction 2025.11.03 - Add support for Debian 13 2024.12.23 - Add support for non-interactive acceptance of Steam license 2024.12.22 - Initial version
To include this scriptlet:
# scriptlet:firewalld/install.shInstall firewalld
To include this scriptlet:
# scriptlet:bz_eval_tui/print_header.shPrint a header message
CHANGELOG: 2025.11.09 - Port from _common to bz_eval_tui 2024.12.25 - Initial version
To include this scriptlet:
# scriptlet:bz_eval_tui/prompt_text.shPrompt user for a text response
Arguments: --default="..." Default text to use if no response is given
Returns: text as entered by user
CHANGELOG: 2025.11.23 - Use is_noninteractive to handle non-interactive mode 2025.01.01 - Initial version
To include this scriptlet:
# scriptlet:bz_eval_tui/prompt_yn.shPrompt user for a yes or no response
Arguments: --invert Invert the response (yes becomes 0, no becomes 1) --default-yes Default to yes if no response is given --default-no Default to no if no response is given -q Quiet mode (no output text after response)
Returns: 1 for yes, 0 for no (or inverted if --invert is set)
CHANGELOG: 2025.12.16 - Add text output for non-interactive and empty responses 2025.11.23 - Use is_noninteractive to handle non-interactive mode 2025.11.09 - Add -q (quiet) option to suppress output after prompt (and use return value) 2025.01.01 - Initial version
To include this scriptlet:
# scriptlet:zabbix/repo-setup.shSetup the Zabbix repo for this OS, shared between agent, agent2, server, and proxy.
To include this scriptlet:
# scriptlet:xvfb/install.shInstall Xvfb and (optionally) a daemon helper
Syntax: install_xvfb [--no-daemon] [--display ] [--service ]
Changelog: 20260216 - Initial version
To include this scriptlet:
# scriptlet:_common/package_remove.shRemove a package with the system's package manager.
Uses Redhat's yum, Debian's apt-get, and SuSE's zypper.
Usage:
package_remove apache2
@param $1..$N string Package, (or packages), to remove. Accepts multiple packages at once.
To include this scriptlet:
# scriptlet:_common/setconfigfile_orappend.shUse sed to set a line in a config file
If the target line does not exist, it will simply get appended to the end
Arguments: $1 Line match $2 Line replace $3 filename
Example: setconfigfile_orappend "^Password=.*" "Password=1234" "/etc/myapp/myapp.conf"
CHANGELOG: 2025.04.10 - Escape '?' characters in the sed search
To include this scriptlet:
# scriptlet:_common/random_password.shGenerate a random password, (using characters that are easy to read and type)
To include this scriptlet:
# scriptlet:_common/print_header.shTo include this scriptlet:
# scriptlet:_common/require_root.shTo include this scriptlet:
# scriptlet:_common/get_wan_ip.shTry to retrieve the WAN IP of this device based on ipify.org
CHANGELOG: 2025.12.15 - Use cmd_exists to fix regression bug 2025.11.23 - use which -s for cleaner checks 2025.11.09 - Initial version
To include this scriptlet:
# scriptlet:_common/get_firewall.shGet which firewall is enabled, or "none" if none located
Get which firewall is available on the local system, or "none" if none located
CHANGELOG: 2025.12.15 - Use cmd_exists to fix regression bug 2025.04.10 - Switch from "systemctl list-unit-files" to "which" to support older systems
To include this scriptlet:
# scriptlet:_common/prompt_text.shPrompt user for a text response
Arguments: --default="..." Default text to use if no response is given
Returns: text as entered by user
To include this scriptlet:
# scriptlet:_common/cmd_exists.shSimple wrapper to emulate which -s
The -s flag is not available on all systems, so this function provides a consistent way to check for command existence without having to include '&>/dev/null' everywhere.
Returns 0 on success, 1 on failure
Arguments: $1 - Command to check
CHANGELOG: 2025.12.15 - Initial version (for a regression fix)
To include this scriptlet:
# scriptlet:_common/firewall_allow.shscriptlet:_common/get_firewall.sh
Add an "allow" rule to the firewall in the INPUT chain
Arguments:
--port Port(s) to allow
--source
Specify multiple ports with --port '#,#,#' or a range --port '#:#'
CHANGELOG: 2025.11.23 - Use return codes instead of exit to allow the caller to handle errors 2025.04.10 - Add "--proto" argument as alternative to "--tcp|--udp"
To include this scriptlet:
# scriptlet:_common/download.shSimple download utility function
Uses either cURL or wget based on which is available
Downloads the file to a temp location initially, then moves it to the final destination upon a successful download to avoid partial files.
Returns 0 on success, 1 on failure
Arguments: --no-overwrite Skip download if destination file already exists
CHANGELOG: 2025.12.15 - Use cmd_exists to fix regression bug 2025.12.04 - Add --no-overwrite option to allow skipping download if the destination file exists 2025.11.23 - Download to a temp location to verify download was successful
- use which -s for cleaner checks 2025.11.09 - Initial version
To include this scriptlet:
# scriptlet:_common/os_version.shGet the operating system version
Just the major version number is returned
To include this scriptlet:
# scriptlet:_common/is_noninteractive.shDetermine if the current shell session is non-interactive.
Checks NONINTERACTIVE, CI, DEBIAN_FRONTEND, and TERM.
Returns 0 (true) if non-interactive, 1 (false) if interactive.
CHANGELOG: 2025.12.16 - Remove TTY checks to avoid false positives in some environments 2025.11.23 - Initial version
To include this scriptlet:
# scriptlet:_common/os.shGet the operating system
almalinux, alpine, amzn, antergos, arch, archarm, arcolinux, centos, clear-linux-os, clearos, debian, elementary, endeavouros, fedora, freebsd, gentoo, kali, linuxmint, mageia, manjaro, nixos, opensuse, ol, pop, raspbian, rhel, rocky, scientific, slackware, sles, ubuntu, virtuozzo
To include this scriptlet:
# scriptlet:_common/os_like.shCheck if the OS is "like" a certain type
Returns 0 if true, 1 if false
Usage: if os_like debian; then ... ; fi
Check if the OS is "like" a certain type
ie: "ubuntu" will be like "debian"
Returns 0 if true, 1 if false Prints 1 if true, 0 if false
Usage: if [ "$(os_like_debian)" -eq 1 ]; then ... ; fi if os_like_debian -q; then ... ; fi
Check if the OS is "like" a certain type
ie: "ubuntu" will be like "debian"
Returns 0 if true, 1 if false Prints 1 if true, 0 if false
Usage: if [ "$(os_like_ubuntu)" -eq 1 ]; then ... ; fi if os_like_ubuntu -q; then ... ; fi
Check if the OS is "like" a certain type
ie: "ubuntu" will be like "debian"
Returns 0 if true, 1 if false Prints 1 if true, 0 if false
Usage: if [ "$(os_like_rhel)" -eq 1 ]; then ... ; fi if os_like_rhel -q; then ... ; fi
Check if the OS is "like" a certain type
ie: "ubuntu" will be like "debian"
Returns 0 if true, 1 if false Prints 1 if true, 0 if false
Usage: if [ "$(os_like_suse)" -eq 1 ]; then ... ; fi if os_like_suse -q; then ... ; fi
Check if the OS is "like" a certain type
ie: "ubuntu" will be like "debian"
Returns 0 if true, 1 if false Prints 1 if true, 0 if false
Usage: if [ "$(os_like_arch)" -eq 1 ]; then ... ; fi if os_like_arch -q; then ... ; fi
Check if the OS is "like" a certain type
ie: "ubuntu" will be like "debian"
Returns 0 if true, 1 if false Prints 1 if true, 0 if false
Usage: if [ "$(os_like_bsd)" -eq 1 ]; then ... ; fi if os_like_bsd -q; then ... ; fi
Check if the OS is "like" a certain type
ie: "ubuntu" will be like "debian"
Returns 0 if true, 1 if false Prints 1 if true, 0 if false
Usage: if [ "$(os_like_macos)" -eq 1 ]; then ... ; fi if os_like_macos -q; then ... ; fi
To include this scriptlet:
# scriptlet:_common/package_install.shInstall a package with the system's package manager.
Uses Redhat's yum, Debian's apt-get, and SuSE's zypper.
Usage:
package_install apache2 php7.0 mariadb-server
@param $1..$N string Package, (or packages), to install. Accepts multiple packages at once.
CHANGELOG: 2026.01.09 - Cleanup os_like a bit and add support for RHEL 9's dnf 2025.04.10 - Set Debian frontend to noninteractive
To include this scriptlet:
# scriptlet:_common/prompt_yn.shPrompt user for a yes or no response
Arguments: --invert Invert the response (yes becomes 0, no becomes 1) --default-yes Default to yes if no response is given --default-no Default to no if no response is given
Returns: 1 for yes, 0 for no (or inverted if --invert is set)
To include this scriptlet:
# scriptlet:proton/install.shInstall Glorious Eggroll's Proton fork on a requested version
https://github.com/GloriousEggroll/proton-ge-custom
Will install Proton into /opt/script-collection/GE-Proton${VERSION} with its pfx directory in /opt/script-collection/GE-Proton${VERSION}/files/share/default_pfx
@arg $1 string Proton version to install
CHANGELOG: 2025.11.23 - Use download scriptlet for downloading 2024.12.22 - Initial version
To include this scriptlet:
# scriptlet:yum/repo_excludepkg.shDisable a package from a given yum repo
To include this scriptlet:
# from scriptlets.steam.steamcmd_get_app_details import *To include this scriptlet:
# from scriptlets.steam.steamcmd_parse_manifest import *Parses a SteamCMD manifest file content and returns a dictionary with the all the relevant information.
Example format of content to parse:
"2131400" { "common" { "name" "VEIN Dedicated Server" "type" "Tool" "parent" "1857950" "ReleaseState" "released" "oslist" "windows,linux" "osarch" "64" "osextended" "" "icon" "7573f431d9ecd0e9dc21f4406f884b92152508fd" "clienticon" "b5de75f7c5f84027200fdafe0483caaeb80f7dbe" "clienttga" "6012ea81d68607ad0dfc5610e61f17101373c1fd" "freetodownload" "1" "associations" { } "gameid" "2131400" } "extended" { "gamedir" "" } "config" { "installdir" "VEIN Dedicated Server" "launch" { "0" { "executable" "VeinServer.exe" "type" "default" "config" { "oslist" "windows" } "description_loc" { "english" "VEIN Dedicated Server" } "description" "VEIN Dedicated Server" } "1" { "executable" "VeinServer.sh" "type" "default" "config" { "oslist" "linux" } "description_loc" { "english" "VEIN Dedicated Server" } "description" "VEIN Dedicated Server" } } "uselaunchcommandline" "1" } "depots" { "228989" { "config" { "oslist" "windows" } "depotfromapp" "228980" "sharedinstall" "1" } "228990" { "config" { "oslist" "windows" } "depotfromapp" "228980" "sharedinstall" "1" } "2131401" { "config" { "oslist" "windows" } "manifests" { "public" { "gid" "3422721066391688500" "size" "13373528354" "download" "4719647568" } "experimental" { "gid" "5376672931011513884" "size" "14053570688" "download" "4881399680" } } } "2131402" { "config" { "oslist" "linux" } "manifests" { "public" { "gid" "4027172715479418364" "size" "14134939630" "download" "4869512928" } "experimental" { "gid" "643377871134354986" "size" "14712396815" "download" "4982816608" } } } "branches" { "public" { "buildid" "20727232" "timeupdated" "1762674215" } "experimental" { "buildid" "20729593" "description" "Bleeding-edge updates" "timeupdated" "1762704776" } } "privatebranches" "1" } }
:param manifest_content: str, content of the SteamCMD manifest file :return: dict, parsed manifest data
To include this scriptlet:
# from scriptlets.steam.steamcmd_check_app_update import *To include this scriptlet:
# from scriptlets.suitecrm.suitecrmsync import *Patch/update a record in SuiteCRM
:param object_type: :param object_id: :param data: :return
create a record in SuiteCRM :param object_type: :param data: :return
:param object_type: :param filters: :param operator: :param fields: :return:
To include this scriptlet:
# from scriptlets.bz_eval_tui.print_header import *To include this scriptlet:
# from scriptlets.bz_eval_tui.prompt_text import *To include this scriptlet:
# from scriptlets.bz_eval_tui.table import *Initialize the table with the columns to display :param columns:
Render the table with the given list of services
:param services: Services[] :return:
To include this scriptlet:
# from scriptlets.bz_eval_tui.prompt_yn import *To include this scriptlet:
# from scriptlets._common.cmd import *Get the output of the command decoded as JSON :return:
To include this scriptlet:
# from scriptlets._common.get_wan_ip import *To include this scriptlet:
# from scriptlets._common.firewall_remove import *To include this scriptlet:
# from scriptlets._common.firewall_allow import *To include this scriptlet:
# from scriptlets._common.require_root import *To include this scriptlet:
# from scriptlets._common.get_firewall import *To include this scriptlet:
# from scriptlets.org_python.venv_path_include import *To include this scriptlet:
# from scriptlets.ssh.get_user_public_key import *To include this scriptlet:
# from scriptlets.ssh.get_user_authorized_keys import *