Every Linux system has at least two accounts: root and whoever set the
machine up. Between those two extremes, real systems accumulate service
accounts, shared project accounts, and the occasional test user that
nobody remembers creating. This guide covers the commands that create,
modify, and remove those accounts – and the four plain-text files that
store them.
If you have never changed a user’s shell or added someone to a group, start here. The commands are short; the consequences are permanent.
Prerequisites
You need root access. Every command in this guide either writes to
/etc/passwd or manipulates account databases that only root can touch.
On Ubuntu/Debian, prefix commands with sudo. On Fedora, either log in
as root or use sudo. On Arch, same deal.
If the language of permissions and ownership feels unfamiliar, read
Permissions & Ownership
first. That chapter covers chmod and chown; this guide covers the
accounts those permissions are assigned to.
useradd – create a user
The basic form is simple:
$ sudo useradd alice
On Ubuntu and Arch, this creates the user but does not create a home
directory. On Fedora, CREATE_HOME=yes is set in /etc/login.defs, so
a home directory at /home/alice is created automatically. This is a
real difference between distros, not a misconfiguration.
To create a home directory on any distro, pass -m:
$ sudo useradd -m alice
This creates /home/alice and copies the skeleton files from
/etc/skel into it. The skeleton directory contains default dotfiles:
.profile on Ubuntu, .bash_profile on Fedora and Arch. These are
templates. They do not affect login behavior until you edit them.
A few flags come up often:
$ sudo useradd -m -s /bin/bash -G sudo,docker -c "Alice Example" alice
-s /bin/bashsets the login shell. Without it,useraddreads the fallback from/etc/default/useradd(theSHELL=line), never from/etc/login.defs. That fallback is/bin/shon Ubuntu and bash on Fedora and Arch, but it differs, so always pass-sto be explicit.-G sudo,dockeradds supplementary groups (the-aGflag onusermoddoes the same for existing users, see below). Know your distro’s admin group: thesudogroup exists on Ubuntu. Fedora and Arch call itwheelinstead (there,useradd -G sudofails withgroup 'sudo' does not exist). And thedockergroup only exists after Docker is actually installed. Until then, that flag is an error too.-c "Alice Example"sets the GECOS comment field, a free-text string that shows up ingrep alice /etc/passwd.
You can also set a custom primary group or UID:
$ sudo useradd -m -g developers -u 2000 carol
-g developerssets the primary group (field 4 in/etc/passwd). Without it,useraddcreates a new group named after the user.-u 2000assigns a specific UID instead of picking the next available one. Useful when UIDs must match across multiple machines.
A custom home directory path works too:
$ sudo useradd -m -d /opt/alice alice
Without -m, the -d flag sets the path in /etc/passwd but does
not create the directory. The user would log in to a missing home
and get errors.
One more thing: useradd does not set a password. The account exists but
is locked until you run passwd (covered later in this guide).
adduser vs useradd – the Debian wrapper
On Ubuntu and Debian, adduser is a higher-level interactive wrapper
written in Perl. It creates the home directory, sets the shell, asks
for a password, then prompts you for the full name – all in one
conversation:
$ sudo adduser alice
On Fedora, adduser is a symlink to useradd. There is no interactive
wrapper; adduser alice behaves identically to useradd alice. On Arch,
adduser does not exist.
If you are writing scripts, always use useradd – it works the same
everywhere. If you are setting up a user by hand on Ubuntu and prefer
the guided experience, adduser is the more pleasant option.
groupadd – create a group
Groups let you grant permissions to multiple users at once. Every user
has one primary group (field 4 in /etc/passwd, the group a new
file is owned by) and zero or more supplementary groups (field 5 in
/etc/group, the extra memberships). The -G flag and usermod -aG
both deal with supplementary groups. -g sets the primary group.
The command to create a group is straightforward:
$ sudo groupadd developers
That creates a new group in /etc/group with the next available GID.
You can add users to it immediately:
$ sudo usermod -aG developers alice
Or create the user with the group already assigned:
$ sudo useradd -m -G developers bob
The difference between -G in useradd and -aG in usermod matters.
In useradd, -G sets the initial supplementary groups. In usermod,
-aG appends to the existing list. Without -a, usermod -G replaces the
entire supplementary group list. Forgetting -a is one of the more
common mistakes in user management – and it is silent. The command does
not warn you that it just removed the user from every other group.
usermod – change an account
usermod edits an existing account. The most common uses:
Change the login shell:
$ sudo usermod -s /bin/zsh alice
(usermod warns that the shell is missing or non-executable, but records it anyway.)
Move a home directory:
$ sudo usermod -d /home/alice-new -m alice
The -m flag moves the existing home contents to the new path. If the
target directory already exists, usermod warns
(usermod: directory /home/X exists, exit code 12) and moves nothing.
But it still repoints the home field in /etc/passwd, silently leaving
the user’s files behind. Check before you run it.
Lock and unlock an account:
$ sudo usermod -L alice # lock
$ sudo usermod -U alice # unlock
Locking prepends a ! to the encrypted password in /etc/shadow. The
account still exists, but no password will authenticate it. SSH key
authentication is not affected by account locking. Only password-based
logins are blocked.
Add to a group (without removing others):
$ sudo usermod -aG developers alice
Again: -aG appends. -G alone replaces.
userdel – remove an account
$ sudo userdel alice
This removes the user entry from /etc/passwd and /etc/group but
leaves the home directory intact. Files owned by the deleted user become
orphaned: they still exist, but their ownership shows a numeric UID
instead of a username.
To remove the user and their home directory:
$ sudo userdel -r alice
The -r flag deletes /home/alice along with the user entry. There is
no undo. If you want to keep the files but reassign ownership, remove
the user first, then chown the files to a different account.
A practical note: never delete a user while they are logged in. The
who command shows who is currently logged in; id <user> shows
membership and UID/GID details. Use either before removing accounts.
The four account files
Linux stores user and group information in four plain-text files in
/etc. Understanding them helps when commands behave unexpectedly.
/etc/passwd – one line per user, seven colon-separated fields:
alice:x:1001:1001:Alice Example:/home/alice:/bin/bash
The fields are: username, password placeholder (x means the real hash
lives in shadow), UID, GID, GECOS comment, home directory, login shell.
/etc/shadow – password hashes and aging data, readable only by root:
On Ubuntu, the permissions are 640. On Fedora, SELinux controls access
(the raw permissions show 000). On Arch, the file is 600. The
details differ, but the rule is the same: regular users cannot read it.
/etc/group – one line per group:
developers:x:1002:alice,bob
Fields: group name, password placeholder (rarely used), GID, comma-separated member list.
/etc/gshadow – group password and administrative data, root-readable
only. The file is not empty: every group gets a line, and the password
field is usually unused (* or !). Group passwords are a relic.
Modern setups use supplementary groups instead.
id and getent – look up accounts
The id command shows who you are:
$ id
uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo),1002(developers)
Or ask about another user:
$ id bob
uid=1001(bob) gid=1001(bob) groups=1001(bob),1002(developers)
Useful flags:
$ id -u # numeric UID only: 1000
$ id -g # numeric GID only: 1000
$ id -n -u # username only: alice
$ id -n -g # group name only: alice
These flags are handy in scripts where you need a number, not a display string.
getent queries the system databases directly. It reads the same files
id does, but can target a specific database:
$ getent passwd alice
alice:x:1001:1001:Alice Example:/home/alice:/bin/bash
$ getent group developers
developers:x:1002:alice,bob
The difference from reading /etc/passwd with cat is that getent
respects NSS. If your system uses LDAP, SSSD, or another directory
service, getent returns entries from those sources too. Plain cat
would only show the local files.
passwd and chage – passwords and expiry
A user without a password cannot log in via password authentication. As root, set one:
$ sudo passwd alice
The system prompts for a new password twice. How chatty the strength
check is depends on the distro: Fedora warns on weak passwords out of
the box (BAD PASSWORD: The password is shorter than 8 characters),
while root on Ubuntu and Arch sets weak passwords silently unless the
PAM quality module is installed. They still enforce PAM rules if
configured.
Password aging controls how long a password remains valid. The chage
command manages this:
$ sudo chage -l alice # list current settings
$ sudo chage -M 90 alice # expire password after 90 days
The -l flag displays the current password aging info: last change date,
minimum and maximum age, warning period, and account expiry. The -M 90
flag sets the maximum number of days a password can be used before the
system forces a change.
These settings apply to password-based logins. If you use SSH key authentication exclusively, password expiry policies do not affect your access – but they still matter if someone can fall back to a password.
UID and GID numbers – the numbering scheme
Every user has a numeric UID. Every group has a numeric GID. The convention across major distros:
UID 0 is always root. UIDs 1 through 999 are system accounts: services
like www-data and systemd-resolve that run daemons, not interactive
shells. Regular accounts start at UID 1000.
The first user created on a fresh Ubuntu install gets UID 1000. Fedora
and Arch follow the same pattern. When you create users with useradd,
the system picks the next available UID starting at 1000.
Groups follow an identical scheme: GID 0 is root, 1–999 are system
groups, 1000+ are user groups. The users group exists on most systems
as a fallback (GID 100 on Ubuntu and Fedora, 982 on Arch).
You can check a specific UID:
$ id -u alice
1000
Or see which UID a system account runs as:
$ id -u nobody
65534
UID 65534 (nobody) is the conventional unprivileged account, and the
name matches on all three distros. What drifts is the cosmetic stuff:
Ubuntu’s GECOS string reads nobody, Fedora’s and Arch’s read
Kernel Overflow User, and the nologin path differs
(/usr/sbin/nologin on Ubuntu and Fedora, /usr/bin/nologin on Arch).
Capstone: setting up a shared project account
Suppose a small team needs a shared account for running a deployment
script. The account should have a home directory, a bash shell, and
access to a deploy group that owns the deployment directory.
$ sudo groupadd deploy
$ sudo useradd -m -s /bin/bash -G deploy -c "Deploy Account" deployer
$ sudo passwd deployer
At this point, deployer can log in and has a home directory. The
deployment directory needs to belong to the deploy group:
$ sudo chown root:deploy /opt/deployments
$ sudo chmod 2775 /opt/deployments
The 2775 permission set means the directory is group-writable, and new
files inherit the group. The leading 2 sets the setgid bit: new
files created inside this directory automatically inherit the
directory’s group (deploy here) instead of the creator’s primary
group. Any user in the deploy group, including deployer, can
create and modify files there. One warning: setgid alone does not
stop group members from deleting or renaming each other’s files. That
happens on all three distros. To get both at once (group inheritance
and deletion protection), combine the bits: chmod 3775. New files
still inherit the group, and a non-owner member’s rm now fails with
Operation not permitted.
To add more team members to the group:
$ sudo usermod -aG deploy alice
$ sudo usermod -aG deploy bob
To verify:
$ id deployer
uid=1002(deployer) gid=1002(deployer) groups=1002(deployer),1003(deploy)
$ getent group deploy
deploy:x:1003:deployer,alice,bob
If the team changes and you need to remove someone:
$ sudo userdel -r olduser
Or just remove their group membership without deleting the account.
The gpasswd command manages group membership directly, and -d removes
a user from a group:
$ sudo gpasswd -d olduser deploy
Where you are now
You have the full lifecycle of Linux accounts: creating users with
useradd, groups with groupadd, modifying accounts with usermod,
removing them with userdel, and reading the four files that hold it
all. The commands are short; the work is knowing which flag means what
and which distro does it differently.
For the permissions those accounts inherit, see Permissions & Ownership. For the services accounts run and the logs they produce, see Services & Logs. If something goes wrong (a locked account, a missing home, a group that does not seem to stick), Troubleshooting covers the common failure patterns.
External references:
useradd(8)man page – the authoritative list of flags and defaults- ArchWiki: Users and groups – comprehensive cross-distro reference with detailed explanations of UID/GID numbering and group management
login.defs(5)man page – documentsCREATE_HOME, UID ranges, and password aging defaults