newgrp Command: Tutorial & Examples

Switch your active group mid-session without logging out — the escape hatch for "I just got added to a group."

What It Is

newgrp changes which group your shell is currently acting as, right now, without you logging out and back in. You ran usermod -aG docker alice, added yourself to a group, and then — infuriatingly — the very next command still says permission denied. You didn't do anything wrong. Your shell was born before the change and is carrying a stale list of groups. newgrp docker is the one-word fix: it starts a fresh shell with the new group baked in, and the permission appears as if by magic.

It's a tiny, ancient, slightly odd command — it predates Linux itself — and it does exactly one thing, which makes it perfect for a first lesson in how Unix permissions actually work. By the end of this page you'll understand the difference between your primary and supplementary groups, why a group membership can exist on disk but not in your running session, and the genuinely surprising reason newgrp is allowed to hand you new powers at all. We'll run it for real, read its output, and pick up a couple of close cousins (sg and id) along the way.

Your First Look

Here's the whole command, live. First, who am I and what groups do I carry? Ask id:

$ id
uid=1000(arndt) gid=1000(arndt) groups=1000(arndt),24(cdrom),27(sudo),44(video)

Read that carefully, because it's the entire mental model on one line. uid=1000(arndt) is who I am. gid=1000(arndt) is my primary group — singular, the one that matters most. And groups=... is the full set I belong to: my primary plus every supplementary group (cdrom, sudo, video). I'm a member of all of them at once.

Now watch what newgrp does. I'll switch my primary group to cdrom:

$ newgrp cdrom
$ id
uid=1000(arndt) gid=24(cdrom) groups=24(cdrom),27(sudo),44(video),1000(arndt)

Look at what moved. gid flipped from 1000(arndt) to 24(cdrom)cdrom is now my primary group. And in the groups= list, cdrom jumped to the front while my old primary, 1000(arndt), got bumped to the back. I didn't gain or lose any membership — I was already in cdrom. I just changed which one is the active primary. Type exit and the original shell, with its original gid, is sitting right there waiting for me, untouched.

That's the shape of it. Now let's learn to read it the way it pays to.

How I Use It

In real life I reach for newgrp for exactly one reason, and it's worth burning into memory because it saves a reboot every single time.

The pattern: I just added myself to a group, and it "didn't work." Classic first day with Docker:

$ sudo usermod -aG docker alice
$ docker ps
permission denied while trying to connect to the Docker daemon socket

The membership is on disk — check /etc/group and alice is right there in the docker line. But my shell can't see it, and here's the why, which is the whole magic of this page: your group membership is loaded once, at login, and then frozen for the life of that session. A process inherits its group list from its parent, that parent from its parent, all the way back to the login shell that read /etc/group the moment you signed in. Edit the file afterwards and not one running process notices — they're all working from a snapshot taken before the edit. (This is the same reason a freshly-changed PATH doesn't show up in old terminals. Sessions don't get told about the world changing under them.)

So the textbook fix is "log out and back in," which re-reads everything. But that's heavy — close every editor, drop every SSH session, lose your place. newgrp docker does the same re-read for one group in one second:

$ newgrp docker
$ docker ps
CONTAINER ID   IMAGE   ...

Done. No logout, no reboot, no tweet about how "you have to restart Linux to join a group" (you don't). The new shell newgrp spawned pulled a fresh group list straight from /etc/group, so docker is finally live.

Pro Tip

If you only need to run one command under a different group, don't spawn a whole shell — use sg (newgrp's twin) instead: sg docker -c 'docker ps'. It runs the single command with the group active and drops you straight back, no nested shell to remember to exit.

What Actually Happens Under the Hood

This is the part that turns newgrp from a magic word into something you understand. Three things happen when you run it, and the third one is the surprise.

1. It starts a brand-new shell. newgrp does not edit your current shell — it can't; a process can't rewrite its own credentials from the outside. Instead it launches a fresh child shell with the new group set, and your terminal is now talking to that child. Proof: the shell's PID changes the moment you run it. That's why exit (not a second newgrp) is how you get back — you're literally stacking shells, and exit pops the top one off. Run newgrp three times and you've got three nested shells; you'll exit three times to unwind them.

2. It re-reads /etc/group from scratch. The new shell builds its group list fresh from disk, which is precisely why a membership added a moment ago suddenly works.

3. It can switch you into a group you're not even a member of — if you know the password. This is the genuinely strange one. /etc/group lines can carry a group password (stored hashed in /etc/gshadow, set with gpasswd). If a group has one, anyone who knows it can newgrp into it, member or not — newgrp prompts for the password and lets them in. It's a near-forgotten relic from an era when a handful of people shared one machine and a spoken password was how you joined a project's group for an afternoon. Almost nobody sets group passwords today, and you shouldn't — but it explains a detail that otherwise makes no sense:

$ ls -l /usr/bin/newgrp
-rwsr-xr-x 1 root root 18816 /usr/bin/newgrp

See that s where the owner's x should be? That's the setuid bit, and it means newgrp runs as root no matter who launches it. A normal program can't change its own group ID to something privileged — that's a kernel-guarded operation. So newgrp borrows root's authority just long enough to set the new GID, after first checking you're actually allowed (you're a member, or you typed the group password). It's a tiny, carefully-scoped use of root power, and the setuid bit is the hinge the whole command swings on.

The Arguments, Explained

newgrp has almost no surface area — which is part of its charm. Here's every form:

  • newgrp (no argument) — resets your primary group back to your login group, the gid you started the session with. The undo button if you've switched around.
  • newgrp groupname — switch your primary group to groupname and start a fresh shell. The common case.
  • newgrp - groupname — the leading - (a lone dash) re-initializes the whole environment as if you'd freshly logged in, not just the group. Same idea as the dash in su -: a clean slate rather than a continuation. Rarely needed.
  • newgrp groupname command — run command under the new group instead of opening an interactive shell. (The sg form below is the more common way to do this.)
  • -c command, --command=command — pass a command to the shell with -c, the explicit version of the above.
  • -h, --help / -V, --version — the usual.

And its twin, sg ("set group"), which is literally the same binary — on a modern util-linux box /usr/bin/sg is a symlink to newgrp:

$ ls -l /usr/bin/sg
lrwxrwxrwx 1 root root 6 /usr/bin/sg -> newgrp

The behavior split is just: invoked as newgrp, it defaults to an interactive shell; invoked as sg, it expects a command. So:

$ sg cdrom -c 'id -gn'
cdrom

One command, the right group, and you're immediately back where you were. sg is the form you'll actually want inside scripts and one-liners.

Reading It by Example

A gallery of what you'll see, and what each one is telling you:

newgrp docker followed by a working docker ps → the membership existed on disk all along; your old shell just hadn't loaded it. Textbook, the reason this command exists.

id shows gid=24(cdrom) and cdrom at the front of groups=, old primary at the back → you're mid-switch. Everything is fine; this is exactly what a successful newgrp cdrom looks like. The reordering is cosmetic-ish but real: your primary group is the one new files you create will be owned by.

newgrp foo answers newgrp: group 'foo' does not exist → typo, or the group genuinely isn't created yet. Check getent group foo.

newgrp foo prompts you for a passwordfoo has a group password set and either you're not a member or it's demanding it anyway. If you don't know it, you can't switch — and frankly, seeing this in 2020s-and-beyond is a small red flag worth asking about.

You run newgrp, then exit, then id still shows the new group → you're confused about how many shells deep you are. You stacked two newgrps and only popped one. Type exit again. (When in doubt, echo $SHLVL tells you how deep the nesting goes.)

Gotchas

  • exit, not newgrp, returns you. Each newgrp is a new shell layered on top, never a swap. To get your original group back, exit the way you came in — or newgrp with no argument to reset the primary group within the current layer.
  • New files inherit your primary group. This is the practical reason the switch matters. If you're writing into a shared project directory, newgrp project before you start means everything you create is owned by project and your teammates can read it — instead of being stamped with your personal primary group and locking them out. (If the directory has the setgid bit set, it overrides this and forces the directory's group onto new files — often the cleaner fix for a shared folder, and one that doesn't depend on anyone remembering to run newgrp.)
  • It's per-session, not permanent. newgrp changes this shell's view. It edits nothing on disk. Open a new terminal and you're back to your login group — which is correct, because the membership in /etc/group is the real, persistent truth; newgrp only changes which slice of it is active here and now.
  • A command argument runs and exits. newgrp docker docker ps doesn't leave you in a docker-group shell; it runs docker ps and returns. For an interactive session, give it the group and nothing else.
  • It needs the group to exist now. newgrp reads /etc/group at the instant you run it. If a script created the group a moment ago, that's fine — but a typo'd or not-yet-created group fails cleanly.

Cheat Sheet

newgrp docker          # switch primary group to docker, new shell
newgrp                 # reset primary group back to login group
newgrp - project       # full re-init (clean environment, like su -)
sg docker -c 'cmd'     # run ONE command under docker, then return
exit                   # leave the newgrp shell, restore previous group
id                     # see your current gid + full group list
id -gn                 # just the current primary group name
getent group docker    # confirm a group exists and who's in it

The mental shortcut: newgrp to live in a group, sg to visit one, exit to leave, id to check where you are.

History & Philosophy

newgrp is one of the genuinely old ones — it shipped in the First Edition of Unix in 1971, when "the system" was one PDP-11 in a Bell Labs room and the people sharing it organized their files by group. Back then a user belonged to exactly one group at a time. There was no groups= list with a dozen entries; you were in one group, full stop, and if your work spanned two projects you had to switch between them. That's the world newgrp was built for, and it's why the command is shaped the way it is: its entire job was to move you from your one group to your other group. The command is a fossil from before multiple-group membership existed.

Multiple simultaneous groups arrived later — BSD added them around 1980, and POSIX made them standard — and the moment they did, the original reason for newgrp largely evaporated. Today you're in all your groups at once; you rarely need to "switch." Which raises a fair question: why is it still here? Because of the one thing simultaneous membership didn't solve — your primary group, the single one stamped onto every file you create, can still only be one value at a time. newgrp is the only built-in way to change which of your groups holds that one privileged seat, mid-session. A command designed for a constraint that no longer exists found a second life serving the one piece of that constraint that survived. It is, like a surprising amount of Unix, a tool that outlived its own original purpose by being quietly useful in a way nobody planned.

There's a small lesson tucked in here, too, about how Linux thinks. Your identity on the system isn't one number — it's a little bundle the kernel hangs onto for every process: a user ID, a primary group ID, and a list of supplementary group IDs. Permission checks consult that whole bundle. newgrp is just a way to reshuffle the group part of the bundle for a new process — and once you see identity as a mutable bag of IDs a process carries around, a dozen other commands (sudo, su, chgrp, setuid binaries) stop being separate mysteries and become variations on one theme: who is this process allowed to be?

See Also

  • sg — newgrp's twin; run one command under a group without a new shell
  • id — show your current uid, primary group, and full group list
  • groups — just the list of groups you belong to
  • usermod — add yourself to a group on disk (the change newgrp activates)
  • gpasswd — manage group membership and the rare group password
  • chgrp — change the group that owns a file
  • su — switch user; the same "new shell with new credentials" idea
  • group — what a Unix group actually is, and how permissions use it
  • setuid — why newgrp runs as root, explained

Just added yourself to a group and Linux still says "permission denied"?

That's a stale session, not a broken machine — and CleverUptime watches for the real permission and service problems that don't fix themselves, flagging them in plain language before they page you at 3am.

Want to see your own server's health right now? One command, no signup, no install.

Check your server →