1

Is there a concise linux command (that will work on OSX) to change permissions on folders and all of their contents, but leave files in the current directory untouched? For example:

/parent/folder1 <-change permissions
/parent/folder2 <-change permissions
/parent/folder3 <-change permissions
/parent/folder3/file1 <-change permissions
/parent/folder3/file2 <-change permissions
/parent/file1 <-do not change permissions
/parent/file2 <-do not change permissions

Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
Michael Prescott
  • 655
  • 2
  • 9
  • 15

6 Answers6

8

You would need to run 2 commands I believe. This is one way to do it:

# find . -mindepth 1 -type d | xargs chmod 700
# find . -mindepth 2 | xargs chmod 700

The first does directories at the current directory level and deeper. The second does all files and directories deeper than the current directory.

djhowell
  • 1,192
  • 7
  • 9
  • 1
    Be careful with xargs, as it will most likely fail whenever the files/folders have spaces in their names. (it's possible to solve this passing some parameters to xargs... but is it really worth the trouble? It's easier to find -exec) – Denilson Sá Maia Apr 28 '10 at 13:17
  • What Denilson said. Especially on macs, many files have spaces in them. – Sirch Apr 21 '13 at 08:50
4

This will change the permissions of every directory in the current directory and all files and folders within them, I think that's what you want but be careful because of the recursion...

find . -maxdepth 1 -type d -exec chmod -R 700 {} \;
JamesHannah
  • 1,731
  • 2
  • 11
  • 24
3

You may use find for this or maybe, with a loop, for:

for directory in parent/*; do if [ -d $directory ]; then chmod -R 700 $directory; fi ;done
Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
Ali Mezgani
  • 3,850
  • 2
  • 24
  • 36
1

There is one trivial case where chmod can do this on its own. If you set mode +X (note, capital, not lowercase), it will only apply to directories. This is commonly used for cases where you want to make all files in a directory tree group or world readable. You would do something like this:

chmod a+rX somedir

This will add read and execute permission to somedir and all directories beneath it, but just read permission to regular files beneath it. There unfortunately is no corresponding mode for read/write permissions, though.

James Sneeringer
  • 6,835
  • 24
  • 27
  • Nice. I didnt know about the X option. OP wanted to chmon on files in lower directories, this doesnt do that though. – Sirch Apr 21 '13 at 08:52
0
find  . -type d -mindepth 1 -print -exec chmod 755 {}/* \;

Find every subdirectory of the current directory (-type d and -mindepth 1), and run chmod for all files in each directory found.

{} refers to the directory find is evaluating, and /* tells chmod to operate on just the files in that directory.

0

Here's the one-liner for the general case:

find /parent -maxdepth 1 -type d -print0 | xargs -0 chmod -R 700

The -print0 and -0 arguments use NUL instead of newline as a record separator, so this is safe for filenames with spaces, newlines, and so on. And unlike -exec, it batches filenames into fewer invocations of chmod.

Bonus:

In cases where you know you don't have hidden directories at the top level of /parent (like /parent/.foo) it's even easier:

chmod -R 700 /parent/*/
tomclegg
  • 301
  • 1
  • 2