Last active
May 18, 2025 20:52
-
-
Save bumbummen99/fdef28a91ec1cf29569b07b7e837af50 to your computer and use it in GitHub Desktop.
Small rsync script to copy media from a library to another library
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 | |
# Configure common information | |
LIBRARIES=("Filme" "Serien" "Musik") | |
######################### | |
# Argument: Destination # | |
######################### | |
# Ceck if there is an argument | |
if [ -n "$1" ]; then | |
# Use the argument as the destination | |
DESTINATION="$1" | |
else | |
# Read the destination from user input | |
read -ep "Please enther the destination library's path: " DESTINATION | |
fi | |
################################### | |
# Optional Argument: Sources list # | |
################################### | |
SOURCES_LIST="" | |
if [ -n "$2" ]; then | |
if [ -f "$2" ]; then | |
SOURCES_LIST="$2" | |
else | |
echo "The provided list '$2' does not exist or is not a file." | |
exit 1 | |
fi | |
fi | |
########### | |
# Sources # | |
########### | |
# Inform the user on how to enter sources | |
echo "Enter the individual paths you want to synchronize to the destination library ($DESTINATION)." | |
echo "Use ENTER to confirm the entered path. Enter an empty path to begin the synchronization." | |
# Collect the sources provided by user input | |
SOURCES=() | |
if [ -n "$SOURCES_LIST" ]; then | |
# Read paths from file | |
while IFS= read -r LINE || [ -n "$LINE" ]; do | |
# Skip empty lines or lines starting with # | |
[[ -z "$LINE" || "$LINE" =~ ^# ]] && continue | |
if [ ! -e "$LINE" ]; then | |
echo "Warning: The path in file does not exist: $LINE" | |
else | |
SOURCES+=("$LINE") | |
fi | |
done < "$SOURCES_LIST" | |
else | |
while true; do | |
read -ep "Path: " SOURCE | |
if [ -z "$SOURCE" ]; then | |
break | |
fi | |
if [ ! -e "$SOURCE" ]; then | |
echo "The provided path does not exist: $SOURCE" | |
else | |
SOURCES+=("$SOURCE") | |
fi | |
done | |
fi | |
# Ensure that any sources have been provided | |
if [ ${#SOURCES[@]} -eq 0 ]; then | |
echo "No paths have been provided, exiting." | |
exit 1 | |
fi | |
########################## | |
# Common relative parent # | |
########################## | |
# Create a temporary directory without leaving the filesystem | |
TMP_DIR=$(mktemp -d) | |
# Link the provided sources to the temporary directory | |
for SOURCE in "${SOURCES[@]}"; do | |
for LIBRARY in "${LIBRARIES[@]}"; do | |
# Check if the source is within the current library | |
if [[ "$SOURCE" == *"/$LIBRARY/"* ]]; then | |
# Extract the relative path starting from the library (e.g., Filme/Alien/Alien 1) | |
RELATIVE_PATH="${SOURCE#*"/$LIBRARY/"}" | |
RELATIVE_PATH="$LIBRARY/$RELATIVE_PATH" | |
# Create the necessary directories in the temp directory | |
mkdir -p "$TMP_DIR/$(dirname "$RELATIVE_PATH")" | |
# Create a symbolic link to the source in the temp directory | |
ln -s "$SOURCE" "$TMP_DIR/$RELATIVE_PATH" | |
break | |
fi | |
done | |
done | |
############### | |
# Synchronize # | |
############### | |
# Initialize the rsync arguments list | |
ARGS=() | |
# Functionality | |
ARGS+=("--relative") # Use relative paths to keep path structure | |
ARGS+=("--recursive") # Sync provided sources recursively | |
ARGS+=("--no-inc-recursive") # Recurse before starting sync to prevent invalid / incrementing estimates in the output | |
ARGS+=("--copy-links") # Sync the symlinks in TMP_DIR as regular folders / files | |
ARGS+=("--times") # Set modified time to prevent unecessary writes in case nothing changed | |
# Configure the output | |
ARGS+=("--verbose") # Use verbose output | |
ARGS+=("--info=progress2") # Show progress of the sync operation | |
ARGS+=("--info=name0") | |
# Dry run rsync to show the changes to be made by the sync | |
rsync "${ARGS[@]}" --dry-run --itemize-changes "$TMP_DIR/" "$DESTINATION" | |
# Ask the user to confirm the changes | |
if read -rp "Do you want to proceed with the changes above? (y/n): " ANSWER && [[ "$ANSWER" =~ ^[Yy]$ ]]; then | |
# Run the final rsync command to sync | |
rsync "${ARGS[@]}" "$TMP_DIR/" "$DESTINATION" | |
else | |
echo "Cancelled synchronization." | |
fi | |
########### | |
# Cleanup # | |
########### | |
# Remove the temporary directory | |
rm -rf "$TMP_DIR" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment