5

I'm having some trouble trying to remove write permission from the owning group (g), and to add read permission to others (o) at the same time.

How would I remove some permission from the owning group and add some permission for others in the same line?

  • Hello and welcome on UL. I find this question rather unclear. Don't hesitate to provide more context and example of desired behaviour so that it'll be easier for people to understand what you mean :) – iago-lito Sep 9 '18 at 21:22
10

Noting the title of your question:

Removing and adding permission using numerical notation on the same line

With chmod from GNU coreutils, which you probably have on a Linux system, you could use

$ chmod -020,+004 test.txt

to do that. It works in the obvious way: middle digit for the group, 2 is for write; and last digit for "others", and 4 for read.

Being able to use + or - with a numerical mode is a GNU extension, e.g. the BSD-based chmod on my Mac gives an error for +004:

$ chmod +004 test.txt
chmod: Invalid file mode: +004

So it would be simpler, shorter, more portable and probably more readable to just use the symbolic form:

$ chmod g-w,o+r test.txt
  • Upvoting because it's almost always best to write symbolic form rather than numeric. I've found by painful experience that people often make errors with numerical form of chmod when they think they're adding permissions but are actually removing some as well. This GNU extension at least avoids that problem, but precisely because it's not POSIX, one must be careful to only use it in a domain where it's assured to be supported. – Monty Harder Sep 10 '18 at 15:25
5

EDIT: Seeing ilkkachu's answer, made me test this, and the syntax he describes works, but the man page on my system (which I had checked) says

can be either a symbolic representation of changes to make, or an octal number representing the bit pattern for the new mode bits

which was what caused me to write the original answer (below). I guess it's a new change and that they forgot to update the man page.

Original answer below:

The title of your questions mentions "numerical notation", if by that you mean specifying modes as octal numbers, the answer is that you can't specify changes with that, only the new mode of the file(s).

  • You're right, it's not on the man page. GNU likes the info pages, so you need to read them. Or the online manual which is probably generated from the same data. I added a link to it in my answer. – ilkkachu Sep 10 '18 at 9:53
4

As the 2nd line of man page says:

chmod g-w,o+r file

$ man chmod

CHMOD(1)                         User Commands             CHMOD(1)

NAME
       chmod - change file mode bits

SYNOPSIS
       chmod [OPTION]... MODE[,MODE]... FILE...

or the 1st line of chmod --help

Usage: chmod [OPTION]... MODE[,MODE]... FILE...
3

Standardly, only the symbolic form allows adding and removing bits from the current permissions (though see @ilkkachu's answer if you're on a GNU system where chmod supports it with the numerical form as an extension).

With the numerical octal form, the number you give is the new set of permission bits, regardless of what the previous value was.

You could however get the previous value by hand and apply the modifications as a bit-logical operation.

For instance, with zsh:

zmodload zsh/stat
zstat -A mode +mode -- "$file" &&
  perms=$((mode & 8#7777)) &&
  chmod -- $(((perms | 4) & ~ 8#20)) "$file"

That's binary OR (|) with 4 to add the read permission to others and binary AND (&) with the binary NOT (~) of octal 20 to remove the write permissions to group.

For instance, if the previous permission bits (st_mode & 0777) were 0660 (rw-rw----), 0660 | 4 would be 0664 (rw-rw-r--), and 0664 & ~ 020 would be 0644 (rw-r--r--).

Now, I'm not sure why you'd want to do that instead of:

chmod -- g-w,o+r "$file"
0

Since you didn't specify a reason for why you want to do it that way. I'll assume you don't know that it is way faster (and imho more precise) to simply set the desired mode, than to flip the flags one after another.

Explained in simplified terms: Specify 3 numerical values for the set/unset state of all the read, write, and execute flags. For owner, group, and others all at once.

To simplify, I'll stick to 3 digits. But you should look at the rest of the flags too when you get used to this way of doing it.

To simplify even more: These 3 values are separate positional values, and not a three digit number. The first one sets the permissions for owner, the next one sets the permissions for group, and the third, sets the permissions for everyone else (others).

Setting the flags: Now. Determining what each digit means is where some people get confused, but it's really simple when you first learn how it's done.

Here are the flag-values:

  • 1=execute
  • 2=write
  • 4=read

Now, you simply do one position at a time, and add (sum) the desired flag-values together. If you want to set read and execute: 4+1=5. If you want read and write but not execute: 4+2=6.

Examples

| ### | Owner | Group | Others |
| --- |  ---  |  ---  |  ---   |
| 755 |  RWX  |  R-X  |  R-X   |
| 644 |  RW-  |  R--  |  R--   |

Extra info and more examples can be seen here: https://linux.die.net/Linux-CLI/file-permissions.html

So if you want group and others to only have read permission, but owner should have read and write, you simply do chmod 644 FILENAME

Here's a great tutorial: Understanding Linux File Permissions

One last tip: Remember that users need execute permission for directories to list the content.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.