14.1 /etc/passwd: Format, Fields, and Shell Field
Right, let’s talk about /etc/passwd. No, it’s not where your computer’s passwords go—that’s the first and most important misconception to shatter. If it were, it would be the world’s worst-kept secret, sitting there world-readable for any process to peek at. The name is a fossil, a relic from a more trusting, simpler time. The actual password hashes got moved to the more secure /etc/shadow file decades ago. What’s left in /etc/passwd is the public, user-account metadata. Think of it as the phonebook for your system’s users.
This file is a perfect artifact of the Unix philosophy: a plain text file where each line represents one user account, and each piece of information is separated by a colon. It’s simple, stupid, and brilliant. You can parse it with anything: cat, awk, cut, a five-line Python script, your eyeballs. Let’s break down one of these lines. Here’s what my line probably looks like on your average Linux box:
myuser:x:1001:1001:My User,,,:/home/myuser:/bin/bash
Looks like a jumble, right? Let’s dissect it field by field. There are seven colon-separated fields, and you need to know them like the back of your hand.
The Seven Fields Demystified
Username: The user’s login name.
myuserin this case. It’s meant for humans, so it’s usually something recognizable. The maximum length is 32 characters, because of course there’s an arbitrary limit. Don’t try to use uppercase letters or spaces; the system will let you create some truly cursed usernames, but many tools will simply break. Just stick to lowercase and numbers. Trust me.Password: Historically, this held the encrypted password hash. Now, it almost always contains just a literal
x. Thisxis a flag telling the system, “Hey, the real password hash isn’t here. Go look for it in/etc/shadow.” Sometimes you might see*or!!, which are other ways to indicate a locked, inactive account. If you see an actual hash here, you’ve either time-traveled to 1985 or you have a serious security configuration problem.User ID (UID): This is the real identity of the user as far as the kernel is concerned. The username is just a friendly label for us humans; processes and file permissions run on this number. UID 0 is always root, the superuser. UIDs 1-999 are typically reserved for system users and services (e.g.,
www-datamight be UID 33). This keeps them separate from us mere mortals, who usually start at UID 1000. Your UID is your passport on the system.Group ID (GID): This is the user’s primary group ID. This is a bit of a legacy concept. The idea was that when a user creates a file, it would be owned by their user and this primary group. Nowadays, we use supplementary groups (in
/etc/group) for access control, and this primary GID often just points to a group with the same name as the user. It’s mostly a formality, but it’s still there.GECOS Field: This field is a glorious, comma-separated dumpster fire of miscellaneous user information. It’s a holdover from Bell Labs’ GECOS mainframe systems. It can contain the user’s full name, room number, office phone, home phone, and… whatever else. In practice, almost everyone only uses the first part for the full name. The rest is typically blank, as you can see by the three consecutive commas in our example. You can edit this with
chfnif you’re feeling nostalgic.Home Directory: This is the path to the user’s home directory, their personal sandbox on the filesystem. When you log in, this is where your shell starts. If this path is invalid or you
chownit incorrectly, you’ll have a very confused and potentially angry user on your hands.Login Shell: This specifies the command that is executed when this user logs in. This is the field we’re here to really talk about.
The Shell Field: More Than Just Bash
The shell field doesn’t just define your user’s command-line experience; it defines what a “login” even means for that account. Let’s get into the weeds.
The most common entry is /bin/bash (or /usr/bin/bash on some distros). This fires up the Bourne Again SHell, the trusty workhorse we all know. But it’s not the only option. You might see /bin/zsh, /bin/fish, or /bin/tcsh for users who enjoy a more… customized experience.
But here’s where it gets interesting. This field doesn’t have to point to an interactive shell at all. It can be any executable on the system. This is a powerful, and often misunderstood, feature.
A classic example is setting a user’s shell to /usr/sbin/nologin or /bin/false. These aren’t shells; they’re tiny, purpose-built utilities.
# Check what they do
$ /usr/sbin/nologin
This account is currently not available.
$ /bin/false
# ...nothing happens, it just exits immediately with a failure code
You’d use these for system accounts that should never be able to log in interactively. For instance, the user www-data that runs your web server doesn’t need a shell. Setting its shell to nologin is a crucial security hardening step—it slams the door shut on any potential interactive access.
You can get creative. I’ve seen setups where a “guest” user’s shell is set to a custom command that just runs rm -rf ~/* and logs them out. (Please don’t actually do this). The point is, the system will run whatever you put here. It’s a sharp tool, so be careful.
Common Pitfalls and Best Practices
The Invalid Shell: The single biggest mistake is pointing this field to a non-existent binary. If you change my shell to
/bin/imaginary-shelland I try to SSH in, the login will fail spectacularly. The system tries to execute it, fails, and boots me out. Always verify the path. You can see all valid shells on your system in/etc/shells.# Check valid shells cat /etc/shells # Verify a user's shell is valid sudo su - myuser -s /bin/bash # Force a valid shell if you're locked outThe
nologinNuance: Prefer/usr/sbin/nologinover/bin/falsefor service accounts. The former is polite enough to print a message, which will show up in auth logs, making it clear the login was intentionally rejected. The latter just fails silently, which can look like a configuration error.Editing the File: You can edit
/etc/passwddirectly withvipw(which locks the file to prevent corruption) or a text editor. But 99% of the time, you should use the proper tools likeusermod. They handle the logic and error checking for you.# The right way to change a shell sudo usermod -s /bin/zsh myuser # The "I know what I'm doing" way (use vipw to be safe) sudo vipw
So, the shell field is a deceptively simple setting with profound implications. It’s the gatekeeper to a user’s interactive session and a vital tool for locking down system accounts. Respect it, configure it wisely, and for goodness’ sake, double-check your paths.