When automating server tasks like Subversion repository creation, we often need to execute specific commands as different users. A common scenario is creating SVN repositories where the svnadmin create
command must run as the web server user (typically www-data) while the rest of the script executes as root.
Proper permission handling is crucial for security and functionality. The www-data user needs ownership of repository files for the web server to access them, but the setup script often requires root privileges for other operations.
The most straightforward approach is using sudo -u
to execute a single command as another user:
#!/bin/bash
# Verify root privileges
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
# Create repository as www-data
sudo -u www-data svnadmin create /svn/repository
# Continue with root operations
chown -R www-data:www-data /svn/repository
svn mkdir file:///svn/repository/trunk -m "Initial structure"
For systems where sudo isn't available or preferred, you can use su
with the -c
flag:
su www-data -c "svnadmin create /svn/repository"
When switching users, environment variables might not carry over. Use env
to preserve specific variables:
sudo -u www-data env PATH=$PATH svnadmin create /svn/repository
Here's a more complete script demonstrating the pattern:
#!/bin/bash
# Repository creation script
REPO_PATH="/svn/newrepo"
# Validate root
[ "$(id -u)" = "0" ] || { echo "Root required"; exit 1; }
# Create as www-data
sudo -u www-data svnadmin create "$REPO_PATH"
# Post-creation setup
chmod -R 775 "$REPO_PATH"
svn mkdir "file://$REPO_PATH/trunk" -m "Initial trunk"
svn mkdir "file://$REPO_PATH/branches" -m "Initial branches"
svn mkdir "file://$REPO_PATH/tags" -m "Initial tags"
After repository creation, ensure proper permissions:
chown -R www-data:www-data /svn
find /svn -type d -exec chmod 775 {} \;
find /svn -type f -exec chmod 664 {} \;
Add basic error checking to make the script more robust:
sudo -u www-data svnadmin create "$REPO_PATH" || {
echo "Repository creation failed"
exit 1
}
When automating server administration tasks, we often encounter situations where a single command needs to run under a different user context while maintaining the overall script's elevated privileges. In your case with Subversion repository setup, the svnadmin create
command must execute as www-data while other operations require root access.
Here are three robust approaches to handle this scenario:
Method 1: Using sudo -u
#!/bin/bash
# Verify root privileges
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
# Execute as www-data
sudo -u www-data svnadmin create /svn/repository
# Continue with root operations
chown -R www-data:www-data /svn/repository
chmod -R 775 /svn/repository
Method 2: Using su with -c flag
#!/bin/bash
# Root check omitted for brevity
# Execute single command as www-data
su www-data -c "svnadmin create /svn/repository"
# Post-commands as root
svnadmin verify /svn/repository
systemctl restart apache2
Method 3: Heredoc Approach
For more complex operations that might need multiple commands:
#!/bin/bash
su www-data <<'EOF'
svnadmin create /svn/repository
exit
EOF
# Back to root context
ln -s /svn/repository /var/www/html/repo
When implementing these solutions:
- Always validate paths and permissions before operations
- Consider adding error handling with
set -e
or explicit checks - For production scripts, add logging of user context switches
- Test permission inheritance in your specific environment
If you need to maintain environment variables during the switch:
sudo -E -u www-data svnadmin create /svn/repository
Or with su:
su - www-data -c "svnadmin create /svn/repository"