Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does recursive mode on chmod do everything but recursion?

chmod -R 775 *.cgi only changes permissions on the files in the current directory, the files in the subdirectory don't get modified at all. This is the exact same functionality as simply doing chmod 775 *.cgi. I have seen people use solutions such as with find and whatnot. Ok great, but why does -R mode even exist if it doesn't even accomplish anything?

like image 243
Razor Storm Avatar asked Aug 12 '10 22:08

Razor Storm


People also ask

Does chmod work recursively?

Changing permissions with chmod To modify the permission flags on existing files and directories, use the chmod command ("change mode"). It can be used for individual files or it can be run recursively with the -R option to change permissions for all of the subdirectories and files within a directory.

How do I set recursive permissions?

The chmod command with the -R options allows you to recursively change the file's permissions. To recursively set permissions of files based on their type, use chmod in combination with the find command. If you have any questions or feedback, feel free to leave a comment.

What is recursive mode Linux?

Recursive means that Linux or Unix command works with the contains of directories, and if a directory has subdirectories and files, the command works on those files too (recursively).

How do I apply chmod to all subdirectories?

Use chmod -R 755 /opt/lampp/htdocs if you want to change permissions of all files and directories at once. Use find /opt/lampp/htdocs -type d -exec chmod 755 {} \; if the number of files you are using is very large.


5 Answers

Probably because you have no directories named *.cgi. Quoth the manual:

-R Recursively change file mode bits. For each file operand that names a directory, chmod shall change the file mode bits of the directory and all files in the file hierarchy below it.

For example:

$ ls -R
.:
a  a.c  b.c  c.c

./a:
a.c  b.c  sub

./a/sub:
a.c  b.c  
$ chmod -R 444 *.c
$ ls -l
drwxr-xr-x 3 msw msw 4096 2010-08-12 18:07 a
-r--r--r-- 1 msw msw    0 2010-08-12 18:07 a.c
-r--r--r-- 1 msw msw    0 2010-08-12 18:07 b.c
-r--r--r-- 1 msw msw    0 2010-08-12 18:07 c.c
$ : directory a not affected
$ chmod -R u-w a    
$ ls -l a
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 a.c
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 b.c
dr-xr-xr-x 3 msw msw 4096 2010-08-12 18:07 sub
$ ls -l a/sub
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 a.c
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 b.c
$ : got em
like image 122
msw Avatar answered Oct 03 '22 18:10

msw


-R tells chmod to recurse into any directories that are given as arguments.

If you say chmod -R 775 *.cgi, the shell will expand *.cgi into a list of files which match that pattern, and pass that as the list of arguments - so chmod isn't being asked to look into any other directories.

(It will recurse into any directory which matches *.cgi...)

like image 24
Matthew Slattery Avatar answered Oct 03 '22 17:10

Matthew Slattery


To accomplish what you want try

find . -name '*.cgi' -print0 | xargs -0 chmod 755

Here find generates a list of all the file with a .cgi ending from the current directory downward, and passes that list to xargs which applies chmod to each one.

like image 20
dmckee --- ex-moderator kitten Avatar answered Oct 03 '22 16:10

dmckee --- ex-moderator kitten


*.cgi is expanded by your shell to a list of all the file names in the current directory ending in .cgi. Then the shell calls chmod with this list of filenames.

chmod looks at all those file names it got from the shell, changes there modes and would recurse if some of them were directories. But probably none of them are, so there is nothing to recurse.

To find all cgi files in the current directory and its subdirectories, and run chmod on them, you could do:

find . -name '*.cgi' -print0 | xargs -0 chmod 775
like image 20
sth Avatar answered Oct 03 '22 17:10

sth


* is a shell builtin, while -R is a command line option. So chmod will never get * as an argument.

Put the case that foo0.cgi and foo1.cgi are the contents of the directory. If you type chmod -R o+r *.cgi then chmod will get the '-R', 'o+r', 'foo0.cgi' and 'foo1.cgi' as arguments.

What you want to do can be accomplished easily:

find . -iname '*.cgi' | xargs chmod 755
like image 33
tamasd Avatar answered Oct 03 '22 18:10

tamasd