Last active
September 10, 2025 00:12
-
-
Save scruffydan/41ba5881fbc0bdc9d1c1823c087c70f7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| #============================================================================== | |
| # A script to add lines of text to a file if they do not already exist. | |
| # It creates a timestamped backup of the original file before making changes. | |
| # | |
| # Exits with status 1 if the target file does not exist, is not writable, | |
| # or if an error occurs during writing. | |
| # Exits with status 0 on successful completion (lines added or already exist). | |
| #============================================================================== | |
| # --- Configuration --- | |
| # The file you want to modify. This can be a full path, e.g., "/etc/hosts" | |
| TARGET_FILE="/path/to/file" | |
| # Define the lines you want to ensure are in the file. | |
| # Using a Bash array is a clean and safe way to handle lines with spaces | |
| # or special characters. | |
| LINES_TO_ADD=( | |
| 'line to add' | |
| 'line 2 to add' | |
| 'line 3 to add' | |
| 'etc' | |
| ) | |
| # --- Script Logic --- | |
| echo "Starting script. Processing file: $TARGET_FILE" | |
| echo "=================================================" | |
| # 1. Pre-flight checks | |
| # Check if the file exists. If not, exit with an error. | |
| if [ ! -f "$TARGET_FILE" ]; then | |
| # Send error messages to stderr | |
| echo "ERROR: Target file '$TARGET_FILE' does not exist." >&2 | |
| exit 1 | |
| fi | |
| # Check if the file is writable. If not, exit with an error. | |
| if [ ! -w "$TARGET_FILE" ]; then | |
| echo "ERROR: Target file '$TARGET_FILE' is not writable. Try running with sudo." >&2 | |
| exit 1 | |
| fi | |
| # 2. Create a timestamped backup. This runs only if the pre-flight checks passed. | |
| TIMESTAMP=$(date +'%Y-%m-%d_%H-%M-%S') | |
| BACKUP_FILE="${TARGET_FILE}.backup_${TIMESTAMP}" | |
| echo "-> File exists and is writable. Creating backup at: $BACKUP_FILE" | |
| cp "$TARGET_FILE" "$BACKUP_FILE" | |
| if [ $? -ne 0 ]; then | |
| echo "ERROR: Failed to create backup file." >&2 | |
| exit 1 | |
| fi | |
| echo # Adding a newline for better readability | |
| # 3. Iterate over each line and add it if it doesn't exist. | |
| # A flag is used to ensure a newline is only added before the *first* | |
| # new line is written to the file. | |
| first_addition=true | |
| for line in "${LINES_TO_ADD[@]}"; do | |
| # Check if the line already exists in the target file. | |
| # -q : quiet mode, don't output anything. | |
| # -F : treat the string as a fixed string, not a regular expression. | |
| # -x : match the entire line exactly. | |
| if grep -qFx -- "$line" "$TARGET_FILE"; then | |
| echo "EXISTS: $line" | |
| else | |
| echo "ADDING: $line" | |
| # Check if this is the first line we're adding in this run. | |
| if [ "$first_addition" = true ]; then | |
| # Add a newline BEFORE the first added line. | |
| echo -e "\n$line" >> "$TARGET_FILE" | |
| # Set the flag to false so subsequent lines won't get a preceding newline. | |
| first_addition=false | |
| else | |
| # For all other lines, add them without a preceding newline. | |
| echo "$line" >> "$TARGET_FILE" | |
| fi | |
| # Check for write errors after attempting to append. | |
| if [ $? -ne 0 ]; then | |
| echo "ERROR: Failed to write to '$TARGET_FILE'." >&2 | |
| # The file is now partially modified; the backup is crucial for recovery. | |
| exit 1 | |
| fi | |
| fi | |
| done | |
| echo "=================================================" | |
| echo "Script finished successfully." | |
| # 4. Exit with success code 0. | |
| exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment