- About
- Scripts
- Dependencies
- License
- Contributing
- Captive DNS (
captive-dns.bash
) - Linode Dynamic DNS (
linode-dynamic-dns.bash
) - Plex DLP Mirror (
plex-dlp-mirror.bash
) - Plex Update TBA (
plex-update-tba.bash
) - Sonarr Group Notifications (
sonarr-group-notifications.bash
) - Sonarr Update TBA (
sonarr-update-tba.bash
) - Unifi Client Monitor (
unifi_client_monitor.bash
) - Update Plex in Docker (
update-plex-in-docker.bash
) - YouTube to Podcast (
youtube_to_podcast.bash
) - Todo
- Done ✓
This repository contains a collection of Bash scripts designed for various automation and utility tasks. These scripts are primarily passion projects. I have a moderate amount of skill in bash. I am certainly no expert, but I am no novice either. There are likely better ways to execute the flow of logic I am trying to achieve in these scripts! If you have a suggestion, I would welcome a pull request. All scripts require Bash version 4 or greater to run.
Please do not use or expect anything from the 'testing' branch to work. Only scripts from the 'main' branch are polished enough to be expected to work reliably.
If you encounter any issues or have questions, please raise an issue on the GitHub Issues page for the repository.
For bugs, feature requests, and enhancements, reach out via the Issues page. If you just need support, reach out to me on IRC. I idle in #goose
on: ChatSpike, Libera, OFTC, SlashNet, and SnooNet. I usually respond within a few hours of being highlighted.
Below is a list of scripts available in this repository, along with their descriptions, requirements, and installation instructions.
These scripts will generally work by sourcing the "Config" options to a .env
file with the same base file name, and kept in the same directory.
So for example, if you want to use the captive-dns.bash
script, you will need to place captive-dns.env
in the same directory next to it.
The config file names are dynamic to the script file name. So if you wanted to rename captive-dns.bash
to force-dns.bash
, then your config file would need to be force-dns.env
in the same directory.
While the dependencies vary for each script, many depend on Mike Farah's 'yq'. While jq
is great for json, I've found yq
to better suit my needs, as it allows me to parse XML in the same way. There are some that still use jq
as I wrote them before switching to yq
-- I am likely to edit them in the future to depend on yq
instead.
This project is licensed under the MIT License - see the LICENSE file for details.
I welcome any discussion and pull requests, as outlined above. I wrote these scripts for myself, but I'm sharing them with the world, as perhaps they can be useful to others in the same way that they've been useful to me. Scripts in this repository will always be freely available.
If you happen to find these scripts particularly helpful and have a few bucks to spare, you can buy me a drink! No pressure at all, but any support is greatly appreciated!
- Purpose: Manages captive DNS on a UDM Pro, forcing all clients to use a specific DNS server via iptables. This is particularly useful for ensuring devices with hard-coded DNS (like Google Home) use your PiHole.
- Requirements:
- UDM Pro running Unifi v2.4+ (Debian-based)
- BoostChicken's on-boot.d
- Dependencies:
awk
,curl
,date
,grep
,host
,md5sum
,iptables
,sort
- Installation:
- Ensure BoostChicken's on-boot functionality is installed.
- Place the script at
/data/scripts/captive-dns.bash
on your UDM Pro. - Make the script executable:
chmod +x /data/scripts/captive-dns.bash
. - Copy
captive-dns.env.example
tocaptive-dns.env
in the same directory and customize it. - Run
/data/scripts/captive-dns.bash --install
to set up cron and on-boot execution.
- Features:
- Forces DNS via iptables NAT prerouting rules.
- Automatic failover to primary, secondary, or tertiary DNS servers based on availability tests.
- Telegram notifications for DNS status changes and errors.
- Self-update capability (
-u
or--update
). - Manages a lockfile to prevent concurrent execution.
- Purpose: Updates a DNS record in Linode's DNS manager, primarily for keeping a dynamic DNS record current.
- Requirements:
- Dependencies:
awk
,curl
,md5sum
- Dependencies:
- Installation:
- Download the
.bash
script and the.env.example
file. - Rename
linode-dynamic-dns.env.example
tolinode-dynamic-dns.env
and customize it with your Linode API key and domain/record details. - Set the script to run on a cron job at your desired interval.
- Download the
- Features:
- Updates IPv4 (A records) and IPv6 (AAAA records).
- Checks current IP against Linode's record before updating.
- Telegram notifications for successful updates or errors.
- Self-update capability (
-u
or--update
). - Manages a lockfile to prevent concurrent execution.
- Purpose: Searches your Plex Media Server for media items (episodes) titled "TBA" or "TBD" and attempts to refresh their metadata to get the correct titles.
- Requirements:
- Dependencies:
awk
,curl
,md5sum
,yq
- Dependencies:
- Installation:
- Download the
.bash
script and the.env.example
file. - Rename
plex-update-tba.env.example
toplex-update-tba.env
and customize it with your Plex server details. - Set the script to run via a cron job (e.g., hourly).
- Download the
- Features:
- Identifies episodes with "TBA" or "TBD" titles in your Plex library.
- Refreshes metadata for identified items to attempt to update titles.
- Telegram and Discord notifications for renamed items or errors.
- Self-update capability (
-u
or--update
). - Allows ignoring specific Plex libraries, series, seasons, or episodes via the
.env
file. - Manages a lockfile to prevent concurrent execution.
This script is currently undergoing a total rewrite, and will be available again...soon™
Purpose: Groups "On Import" notifications from Sonarr to send a single, consolidated message if multiple episodes of a series are imported around the same time, instead of one notification per episode.Requirements:
* Dependencies:awk
,curl
,jq
,md5sum
,sort
.docker
if Sonarr is in Docker and script is outside.Installation:
1. Download the.bash
script and the.env.example
file.
2. Renamesonarr-group-notifications.env.example
tosonarr-group-notifications.env
and customize it.
3. If using Docker, place script and.env
in a persistently mounted directory (e.g.,/config/
).
4. Make the script executable (chmod +x
) and ensure it's owned by the user/group Sonarr runs as.
5. In Sonarr: Settings > Connect > Add Connection (+ Custom Script).
* Name: Your choice (e.g., Grouped Telegram Notifications).
* Notification Triggers: Check "On Import" ONLY.
* Path: Absolute path tosonarr-group-notifications.bash
(e.g.,/config/sonarr-group-notifications.bash
if in Docker).
* Test and Save.Features:
* Consolidates notifications for multiple episodes from the same series imported close together.
* Uses Sonarr's v3 API.
* Telegram notifications.
* Self-update capability (-u
or--update
).
* Manages a lockfile using PIDs to ensure sequential processing of notifications.
- Purpose: Checks your Sonarr library for files that were imported with "TBA" titles and attempts to rename them by refreshing metadata once the actual episode titles are available. This script is intended to run on the host system, interacting with Sonarr running in Docker.
- Requirements:
- Docker (if Sonarr is Dockerized)
- Dependencies:
awk
,curl
,docker
,jq
,md5sum
- Sonarr setting "Episode Title Requires" should be set to "Only for Bulk Season Releases" or "Never" to allow importing TBA titled episodes.
- Installation:
- Download the
.bash
script and the.env.example
file to your host system. - Rename
sonarr-update-tba.env.example
tosonarr-update-tba.env
and customize it with your Sonarr details. - Set the script to run via a cron job (e.g., hourly).
- Download the
- Features:
- Identifies files with "TBA" or "TBD" in their names within Sonarr's library paths.
- Triggers a series refresh and then a rename command in Sonarr for the affected series/episodes.
- Telegram and Discord notifications for renamed items or errors.
- Self-update capability (
-u
or--update
). - Supports multiple Sonarr instances if they are Docker-based; single host-based instance also supported.
- Ignore lists for libraries, series, and episodes.
- Manages a lockfile to prevent concurrent execution.
- Purpose: Automates the update process for official Plex Media Server Docker containers. It checks the currently running version against the latest available from Plex.tv and, if an update is found and no one is actively using Plex, restarts the container to apply the update.
- Requirements:
- Docker
- Dependencies:
awk
,curl
,docker
,jq
,md5sum
,xmllint
- Installation:
- Download the
.bash
script and the.env.example
file to your Docker host. - Rename
update-plex-in-docker.env.example
toupdate-plex-in-docker.env
and customize with your Plex container name, access token, and other preferences. - Set the script to run via a cron job (e.g., hourly).
- Download the
- Features:
- Fetches the latest Plex version information from plex.tv.
- Compares installed version with the latest available for the specified channel (plexpass, beta, public).
- Checks for active Plex sessions and only proceeds with an update if the server is idle.
- Optional database repair using ChuckPA's DBRepair.sh.
- Clears the Plex Codecs directory before restarting to prevent potential issues.
- Restarts the specified Plex Docker container to apply the update.
- Telegram and Discord notifications for updates and errors.
- Self-update capability (
-u
or--Update
). - Manages a lockfile to prevent concurrent execution.
- Purpose: Converts a YouTube playlist or channel into a podcast RSS feed, downloading audio using
yt-dlp
and generating the necessary XML. - Requirements:
- Dependencies:
awk
,curl
,date
,ffprobe
,md5sum
,mimetype
,qrencode
,sha256sum
,shuf
,sqlite3
,stat
,xmllint
,yq
,yt-dlp
- Dependencies:
- Installation:
- Download the
.bash
script and the.env.example
file. - Rename
youtube_to_podcast.env.example
toyoutube_to_podcast.env
and customize it with your YouTube API key, source URL, and desired podcast details. - Set the script to run via a cron job (e.g., hourly).
- Download the
- Features:
- Downloads audio from YouTube videos in a specified playlist or channel.
- Generates a valid RSS feed (
feed.xml
) for use in podcast players. - Stores video metadata, download status, and file paths in an SQLite database (
.youtube_to_podcast.bash.db
). - Optional SponsorBlock integration to remove sponsored segments from downloaded audio.
- Manages a configurable number of recent episodes to keep (
keepLimit
). - Extracts metadata such as titles, descriptions, and thumbnails from YouTube.
- Calculates episode duration and file sizes for the RSS feed.
- Telegram notifications for errors or successful runs.
- Self-update capability (
-u
or--update
). - Generates a QR code for the podcast feed URL on initial database setup if
qrencode
is available. - Manages a lockfile to prevent concurrent execution.
- Re-write sonarr-group-notifications.bash to new standard, and to fix its behavior
- Update update-plex-in-docker.bash to destroy/re-create the container, rather than just restart it (helps clean up old/unnecessary files)
- Update captive-dns.bash to new standard
- Updated Telegram sending function to support super groups, silent notifications
- Update Docker container IP address detection to deal with containers with multiple networking types
- Update linode-dynamic-dns.bash to new standard
- Update update-plex-in-docker.bash to offer to use ChuckPA's database repair/optimization tool between updates