How to Switch Linux Users by UID Instead of Username: A Technical Guide


4 views

While su username is the standard way to switch users, you can indeed switch directly using a UID with this syntax:

su - $(getent passwd 1001 | cut -d: -f1)

This command pipeline:

  1. Looks up UID 1001 in /etc/passwd via getent
  2. Extracts the username using cut
  3. Passes it to su - for login

Using sudo with UID:

sudo -u \#1001 bash

The backslash escapes the # symbol which indicates a numeric UID rather than username.

Direct exec approach:

exec su - $(id -nu 1001)

When switching by UID:

  • The UID must exist in /etc/passwd
  • You need proper permissions (root or target user's password)
  • Environment variables may differ from normal user switching

This technique is particularly useful when:

# In Docker containers where usernames might not be mapped
docker exec -it container su - \#$(id -u appuser)

# For system users that only have numeric IDs
su - $(getent passwd 33 | cut -d: -f1)  # Common www-data UID

If you get "user does not exist" errors:

# Verify the UID exists
getent passwd 1001

# Check UID range (system vs regular users)
grep -E '^UID_MIN|^UID_MAX' /etc/login.defs

When administering Linux systems, we typically use su -u username to switch users. But what if you only know the UID (User ID) and need to switch to that account? This situation often occurs in automated scripts or when dealing with system users that might not have conventional usernames.

The most straightforward method is using runuser with the --user flag:

runuser --user \#1001

Where 1001 is the target UID. The backslash escapes the # symbol which would otherwise be interpreted as a comment.

If you have sudo privileges, this command works well:

sudo -u \#1001 bash

This spawns a new bash shell as the user with UID 1001.

Both commands accept either usernames or numeric UIDs (prefixed with #) to identify users. This is part of their design to support scripting and automation scenarios where UIDs might be more readily available than usernames.

Here's how you might use this in an automation script:

#!/bin/bash
TARGET_UID=1001

if grep -q "^[^:]*:[^:]*:${TARGET_UID}:" /etc/passwd; then
    runuser --user \#${TARGET_UID} --command="whoami"
else
    echo "User with UID ${TARGET_UID} not found"
fi
  • Always verify the UID exists first (check /etc/passwd)
  • The target user must have a valid shell specified in /etc/passwd
  • Environment variables won't be fully initialized like with su - username
  • For full login environment, consider using sudo -i -u \#UID

If you get "user does not exist" errors despite the UID being valid:

  1. Try both with and without the # symbol
  2. Check if SELinux or AppArmor is blocking the operation
  3. Verify the UID is in /etc/passwd with getent passwd "#1001"