Skip to content

Instantly share code, notes, and snippets.

@holmeszyx
Created August 29, 2025 08:23
Show Gist options
  • Save holmeszyx/1495ec63306564f45d4ead4900b2d66f to your computer and use it in GitHub Desktop.
Save holmeszyx/1495ec63306564f45d4ead4900b2d66f to your computer and use it in GitHub Desktop.
share oh my zsh configuration environment from root user to other normal user.
#!/bin/bash
# share-oh-my-zsh.sh - Share oh-my-zsh configuration from root to another user
# Usage: share-oh-my-zsh.sh [target_user] [--backup]
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root"
exit 1
fi
# Parse arguments
TARGET_USER=""
BACKUP_ENABLED=false
while [[ $# -gt 0 ]]; do
case $1 in
--backup)
BACKUP_ENABLED=true
shift
;;
-*)
print_error "Unknown option: $1"
print_error "Usage: $0 [target_user] [--backup]"
exit 1
;;
*)
if [[ -z "$TARGET_USER" ]]; then
TARGET_USER="$1"
else
print_error "Too many arguments"
print_error "Usage: $0 [target_user] [--backup]"
exit 1
fi
shift
;;
esac
done
# Check if target user is provided
if [[ -z "$TARGET_USER" ]]; then
print_error "Usage: $0 [target_user] [--backup]"
exit 1
fi
# Validate target user exists
if ! id "$TARGET_USER" &>/dev/null; then
print_error "User '$TARGET_USER' does not exist"
exit 1
fi
# Get user information
TARGET_HOME=$(getent passwd "$TARGET_USER" | cut -d: -f6)
TARGET_UID=$(id -u "$TARGET_USER")
TARGET_GID=$(id -g "$TARGET_USER")
ROOT_HOME="/root"
print_info "Target user: $TARGET_USER"
print_info "Target home: $TARGET_HOME"
print_info "Target UID:GID: $TARGET_UID:$TARGET_GID"
print_info "Backup enabled: $BACKUP_ENABLED"
# Check if root oh-my-zsh exists
if [[ ! -d "$ROOT_HOME/.oh-my-zsh" ]]; then
print_error "oh-my-zsh not found in $ROOT_HOME/.oh-my-zsh"
exit 1
fi
# Check if root .zshrc exists
if [[ ! -f "$ROOT_HOME/.zshrc" ]]; then
print_error ".zshrc not found in $ROOT_HOME/.zshrc"
exit 1
fi
print_info "Starting oh-my-zsh sharing process..."
# Create target home directory if it doesn't exist
if [[ ! -d "$TARGET_HOME" ]]; then
print_warning "Target home directory doesn't exist, creating it..."
mkdir -p "$TARGET_HOME"
chown "$TARGET_UID:$TARGET_GID" "$TARGET_HOME"
fi
# Handle existing files based on backup option
if [[ "$BACKUP_ENABLED" == true ]]; then
# Backup existing oh-my-zsh if it exists
if [[ -d "$TARGET_HOME/.oh-my-zsh" ]]; then
print_warning "Existing .oh-my-zsh found, backing up to .oh-my-zsh.backup.$(date +%Y%m%d_%H%M%S)"
mv "$TARGET_HOME/.oh-my-zsh" "$TARGET_HOME/.oh-my-zsh.backup.$(date +%Y%m%d_%H%M%S)"
fi
# Backup existing .zshrc if it exists
if [[ -f "$TARGET_HOME/.zshrc" ]]; then
print_warning "Existing .zshrc found, backing up to .zshrc.backup.$(date +%Y%m%d_%H%M%S)"
cp "$TARGET_HOME/.zshrc" "$TARGET_HOME/.zshrc.backup.$(date +%Y%m%d_%H%M%S)"
fi
else
# Remove existing files without backup
if [[ -d "$TARGET_HOME/.oh-my-zsh" ]]; then
print_warning "Existing .oh-my-zsh found, removing without backup (use --backup to preserve)"
rm -rf "$TARGET_HOME/.oh-my-zsh"
fi
if [[ -f "$TARGET_HOME/.zshrc" ]]; then
print_warning "Existing .zshrc found, removing without backup (use --backup to preserve)"
rm -f "$TARGET_HOME/.zshrc"
fi
fi
print_info "Copying oh-my-zsh directory (excluding git files)..."
# Copy oh-my-zsh directory excluding git-related files and directories
rsync -av \
--exclude='.git' \
--exclude='.github' \
--exclude='.gitignore' \
--exclude='.gitmodules' \
--exclude='*.git*' \
"$ROOT_HOME/.oh-my-zsh/" \
"$TARGET_HOME/.oh-my-zsh/"
print_info "Copying zsh configuration files..."
# Copy .zshrc
cp "$ROOT_HOME/.zshrc" "$TARGET_HOME/.zshrc"
# Copy other zsh-related files if they exist
# for file in .zsh_history .zsh_sessions .zprofile .zshenv .zlogin .zlogout; do
# if [[ -f "$ROOT_HOME/$file" ]]; then
# print_info "Copying $file..."
# cp "$ROOT_HOME/$file" "$TARGET_HOME/$file"
# fi
# done
# Copy .zsh_sessions directory if it exists
# if [[ -d "$ROOT_HOME/.zsh_sessions" ]]; then
# print_info "Copying .zsh_sessions directory..."
# cp -r "$ROOT_HOME/.zsh_sessions" "$TARGET_HOME/.zsh_sessions"
# fi
print_info "Setting ownership and permissions..."
# Set ownership for oh-my-zsh directory
chown -R "$TARGET_UID:$TARGET_GID" "$TARGET_HOME/.oh-my-zsh"
# Set ownership for zsh configuration files
chown "$TARGET_UID:$TARGET_GID" "$TARGET_HOME/.zshrc"
# Set ownership for other zsh files if they were copied
# for file in .zsh_history .zsh_sessions .zprofile .zshenv .zlogin .zlogout; do
# if [[ -e "$TARGET_HOME/$file" ]]; then
# chown -R "$TARGET_UID:$TARGET_GID" "$TARGET_HOME/$file"
# fi
# done
# Set proper permissions
chmod 755 "$TARGET_HOME/.oh-my-zsh"
chmod -R 644 "$TARGET_HOME/.oh-my-zsh"
find "$TARGET_HOME/.oh-my-zsh" -type d -exec chmod 755 {} \;
find "$TARGET_HOME/.oh-my-zsh" -name "*.sh" -exec chmod 755 {} \;
# Set permissions for configuration files
chmod 644 "$TARGET_HOME/.zshrc"
# Set executable permissions for any shell scripts in oh-my-zsh
find "$TARGET_HOME/.oh-my-zsh" -type f \( -name "*.sh" -o -name "*.zsh" \) -exec chmod 755 {} \;
# Update .zshrc to point to the correct oh-my-zsh path if needed
print_info "Updating .zshrc paths if necessary..."
sed -i "s|export ZSH=\"/root/.oh-my-zsh\"|export ZSH=\"$TARGET_HOME/.oh-my-zsh\"|g" "$TARGET_HOME/.zshrc"
sed -i "s|export ZSH=/root/.oh-my-zsh|export ZSH=$TARGET_HOME/.oh-my-zsh|g" "$TARGET_HOME/.zshrc"
print_info "Verifying installation..."
# Verify the installation
if [[ -d "$TARGET_HOME/.oh-my-zsh" ]] && [[ -f "$TARGET_HOME/.zshrc" ]]; then
print_info "✓ oh-my-zsh successfully shared with user '$TARGET_USER'"
print_info "✓ Files copied to: $TARGET_HOME"
print_info "✓ Ownership set to: $TARGET_UID:$TARGET_GID"
# Display some statistics
OH_MY_ZSH_SIZE=$(du -sh "$TARGET_HOME/.oh-my-zsh" | cut -f1)
THEME_COUNT=$(find "$TARGET_HOME/.oh-my-zsh/themes" -name "*.zsh-theme" | wc -l)
PLUGIN_COUNT=$(find "$TARGET_HOME/.oh-my-zsh/plugins" -type d -mindepth 1 -maxdepth 1 | wc -l)
print_info "Installation summary:"
print_info " - oh-my-zsh size: $OH_MY_ZSH_SIZE"
print_info " - Themes available: $THEME_COUNT"
print_info " - Plugins available: $PLUGIN_COUNT"
print_info ""
print_info "To complete the setup, user '$TARGET_USER' should:"
print_info "1. Change their default shell to zsh: chsh -s \$(which zsh)"
print_info "2. Log out and log back in, or run: su - $TARGET_USER"
print_info "3. The oh-my-zsh configuration will be active on next shell session"
else
print_error "Installation verification failed"
exit 1
fi
print_info "oh-my-zsh sharing completed successfully!"
# chsh -s $(which zsh) $(whoami)
print_info "Please run 'chsh -s $(which zsh) $TARGET_USER' to change the default shell to zsh for user '$TARGET_USER'"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment