Bash script to replicate a directory structure

I found a need for this once upon a time. It will descend through a Linux directory, get the permissions, ownership details for all the subdirs and then write a script for you to recreate it somewhere else.

You use it like this.

# Put the script in the parent directory of the one you want to clone and run it.
clone_directory_structure.sh targetdirectory > regenerate_directory_structure.sh

# Then move the script to where you want to clone the directory and run it. 
regenerate_directory_structure.sh 

Script listing

#!/bin/bash

# Check if directory is provided
if [ $# -ne 1 ]; then
    echo "Usage: $0 <directory>"
    echo "Example: $0 /path/to/directory"
    exit 1
fi

# Remove trailing slash if present
TARGET_DIR="${1%/}"
TARGET_BASENAME="$(basename "$TARGET_DIR")"
TARGET_PARENT="$(dirname "$TARGET_DIR")"

# Check if directory exists
if [ ! -d "$TARGET_DIR" ]; then
    echo "Error: Directory '$TARGET_DIR' does not exist"
    exit 1
fi

echo "#!/bin/bash"
echo "# Script generated on $(date)"
echo "# To recreate the directory structure, run this script as root or with sudo"
echo "set -e  # Exit on error"
echo

# Process the target directory itself
echo "# Creating target directory: $TARGET_BASENAME"
echo "mkdir -p \"$TARGET_BASENAME\""

# Get permissions, owner, and group of the target directory
TARGET_PERMS=$(stat -c "%a" "$TARGET_DIR")
TARGET_OWNER=$(stat -c "%U" "$TARGET_DIR")
TARGET_GROUP=$(stat -c "%G" "$TARGET_DIR")

echo "chmod $TARGET_PERMS \"$TARGET_BASENAME\""
echo "chown $TARGET_OWNER:$TARGET_GROUP \"$TARGET_BASENAME\""
echo

# Find all subdirectories and process them
find "$TARGET_DIR" -type d -not -path "$TARGET_DIR" -print0 | while IFS= read -r -d $'\0' dir; do
    # Quote the directory path to handle spaces
    dir="$dir"
    # Get relative path from target directory
    rel_path="${dir#$TARGET_DIR/}"
    
    # Quote the path to handle spaces
    rel_path_quoted="$(printf '%q' "$rel_path")"
    
    # Get permissions in octal
    perms=$(stat -c "%a" "$dir")
    
    # Get owner and group
    owner=$(stat -c "%U" "$dir")
    group=$(stat -c "%G" "$dir")
    
    # Output commands with proper quoting for paths with spaces
    echo "# Creating directory: $TARGET_BASENAME/$rel_path"
    echo "mkdir -p $(printf '%q' "$TARGET_BASENAME/$rel_path")"
    echo "chmod $perms $(printf '%q' "$TARGET_BASENAME/$rel_path")"
    echo "chown $owner:$group $(printf '%q' "$TARGET_BASENAME/$rel_path")"
    echo
done

echo "echo \"Directory structure recreation complete!\""
echo "echo \"Created structure under: $TARGET_BASENAME/\""

Leave a Comment