Complete Guide to Switching Users and Correctly Obtaining HOME Directory in Bash Scripts

Nov 23, 2025 · Programming · 13 views · 7.8

Keywords: Bash scripting | User switching | HOME directory | sudo command | Environment variables

Abstract: This article provides an in-depth exploration of technical details for obtaining the correct HOME directory when switching users in Bash scripts. By analyzing key parameters of the sudo command such as -H, -i, and -s, it explains the environmental differences between login and non-login shells in detail, and offers cross-platform compatible solutions. The paper also discusses secure usage of eval with tilde expansion and behavioral differences across sudo versions, providing practical technical references for system administrators and developers.

Problem Background and Core Challenges

In Bash script development, it's often necessary to switch between different user contexts and execute specific operations. A common technical challenge is: when running a script as the root user, how to correctly switch to another user and obtain that user's $HOME directory path. Directly using the su command to switch users may not update environment variables as expected, leading to script logic errors.

Basic Methods for Obtaining User HOME Directory

If you only need to obtain another user's HOME directory without actually switching user identity, you can use tilde expansion combined with the eval command:

different_user="deploy"
eval echo "~$different_user"

This method directly resolves the user's home directory path through Bash's tilde expansion mechanism. It's important to note that the eval command executes Bash code in the string, so you must ensure the value of the $different_user variable is trustworthy to avoid command injection security risks.

Switching User Identity Using sudo Command

When you need to actually execute commands as another user within a script, the sudo command provides more granular control options. The basic syntax format is:

sudo -H -u username command [arguments]

The -H parameter is crucial here, as it ensures the target process uses the specified user's HOME directory environment. If this parameter is omitted, even after switching user identity, the $HOME environment variable will still point to the original user's home directory.

Differences Between Login and Non-Login Shells

The sudo command provides two shell execution modes that significantly impact environment setup:

Login Shell Mode (-i parameter)

sudo -u username -i command

This mode simulates a complete user login process: loads the user's shell configuration files (such as ~/.bash_profile), sets the correct $HOME environment variable, and changes the working directory to the user's home directory. In this mode, there's no need to additionally specify the -H parameter.

Non-Login Shell Mode (-s parameter)

sudo -u username -H -s command

This mode only starts a shell without executing the complete login流程. It doesn't load the user's login configuration files but does load interactive shell initialization files (such as ~/.bashrc). You must explicitly specify the -H parameter to ensure the $HOME variable is set correctly, and the working directory remains the same as the calling process.

Cross-Platform Compatibility Considerations

Different operating systems and sudo versions have variations in parameter processing and shell expansion:

In Linux systems, newer sudo versions (1.8.9p5 and above) support direct variable expansion for arguments passed to the shell:

sudo -u root -H -s echo '$HOME'

To ensure compatibility with older versions, it's recommended to use eval to wrap the command:

sudo -u root -H -s eval 'echo $HOME'

macOS's sudo implementation allows directly passing complete command lines without eval wrapping:

sudo -u root -s 'echo $SHELL - $USER - $HOME - $PWD'

Environment Variables and Security Identification

Processes executed through sudo set specific environment variables to identify the calling context:

These variables are very useful for auditing and debugging, allowing accurate tracking of command execution sources.

Practical Application Examples

Here's a complete script example demonstrating how to safely switch users and operate in their HOME directory within a deployment script:

#!/bin/bash

# Define target user
target_user="deploy"

# Ensure user exists
if ! id "$target_user" &>/dev/null; then
    useradd -m -s /bin/bash "$target_user"
fi

# Method 1: Only obtain HOME directory (without switching users)
home_dir=$(eval echo "~$target_user")
echo "Home directory for user $target_user: $home_dir"

# Method 2: Execute commands as target user (login shell)
echo "Executing commands as $target_user..."
sudo -u "$target_user" -i bash -c '
    echo "Current user: $(whoami)"
    echo "HOME directory: $HOME"
    echo "Working directory: $(pwd)"
    # Add specific commands that need to be executed in user context here
'

# Method 3: Execute commands as target user (non-login shell, specified working directory)
echo "Executing commands in specified directory..."
sudo -u "$target_user" -H -s bash -c '
    cd /tmp
    echo "Current working directory: $(pwd)"
    echo "HOME directory: $HOME"
'

Security Best Practices

When implementing user switching functionality, follow these security principles:

Conclusion

Correctly switching users and obtaining HOME directories in Bash scripts requires deep understanding of various sudo command parameters and their impact on the environment. By appropriately selecting parameters such as -H, -i, and -s, you can precisely control the execution environment of target processes. Simultaneously, consider cross-platform compatibility and security factors to ensure scripts run reliably in various environments. Mastering these technical details is crucial for developing robust system administration scripts.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.