You are not logged in.
Pages: 1
How do I set Chmod to recursively go through a directory structure and set only the directories to a specific permission?
I realize that in order to access a directory, I need to set the 'x' permission, but I do not wish to change the permissions for the images contained in these directories.
Thank you
Offline
hmmm...
maybe with find..
find /path/to/dir -type d -exec chmod 755 {} ;
"Be conservative in what you send; be liberal in what you accept." -- Postel's Law
"tacos" -- Cactus' Law
"t̥͍͎̪̪͗a̴̻̩͈͚ͨc̠o̩̙͈ͫͅs͙͎̙͊ ͔͇̫̜t͎̳̀a̜̞̗ͩc̗͍͚o̲̯̿s̖̣̤̙͌ ̖̜̈ț̰̫͓ạ̪͖̳c̲͎͕̰̯̃̈o͉ͅs̪ͪ ̜̻̖̜͕" -- -̖͚̫̙̓-̺̠͇ͤ̃ ̜̪̜ͯZ͔̗̭̞ͪA̝͈̙͖̩L͉̠̺͓G̙̞̦͖O̳̗͍
Offline
And if that doesn't work perhaps the following will:
d=true; while [ $d ]; do d=`find . -type d ! -perm +ugo=x `; chmod ugo+x $d; echo $d ; done
It will end with an error message of chmod, when $d is empty: that's expected and a sign that it works. ;-)
Offline
How do I set Chmod to recursively go through a directory structure and set only the directories to a specific permission?
I realize that in order to access a directory, I need to set the 'x' permission, but I do not wish to change the permissions for the images contained in these directories.
Thank you
you'r ought to use "find" which happens to have a "not so nice" syntax. Find works recursivly, except from involving the maxdepth=x option the limits number dirs affected in of recursion.
find /path/to/dir # start find command in that dir, looks tthrough everything in it
-type d # find directories only
-exec # find returns the fully qualified path of the result, use that as an argument for a command
chmod 755 {} #the command, {} is the placeholder for the result
; # finish the command by ; but mask it by for bash
you better write the command on one line, though
-neri
Offline
And if that doesn't work perhaps the following will:
d=true; while [ $d ]; do d=`find . -type d ! -perm +ugo=x `; chmod ugo+x $d; echo $d ; done
It will end with an error message of chmod, when $d is empty: that's expected and a sign that it works. ;-)
This one appeared to work until it hit some directories with spaces (these were copied from a windows partition).
I don't suppose you have a script handy to traverse a directory tree and replace any spaces with an underscore?
Thank you,
Offline
hmmm...
maybe with find..find /path/to/dir -type d -exec chmod 755 {} ;
Thank you. This appears to have worked wonderfully.
Offline
nexist wrote:How do I set Chmod to recursively go through a directory structure and set only the directories to a specific permission?
I realize that in order to access a directory, I need to set the 'x' permission, but I do not wish to change the permissions for the images contained in these directories.
Thank you
you'r ought to use "find" which happens to have a "not so nice" syntax. Find works recursivly, except from involving the maxdepth=x option the limits number dirs affected in of recursion.
find /path/to/dir # start find command in that dir, looks tthrough everything in it -type d # find directories only -exec # find returns the fully qualified path of the result, use that as an argument for a command chmod 755 {} #the command, {} is the placeholder for the result ; # finish the command by ; but mask it by for bash
you better write the command on one line, though
-neri
Thank you. I never realized that Find had an exec switch.
Offline
Hey, I clearly said that you should try my version if that other one didn't work. Luckily it did, as I never thought about spaces in filenames, as I avoid those for obvious reasons.
Offline
Hey, I clearly said that you should try my version if that other one didn't work. Luckily it did, as I never thought about spaces in filenames, as I avoid those for obvious reasons.
I know, but I worked my way up from the bottom, so I actually tried yours first. Now I am trying to figure out an easy way to convert about 40 G of MP3's & images so that they no longer have spaces, comma's, etc in them.
Offline
No problem, but it may be dangerous to execute my scripts, that's why they should be only used as a last resort. ;-)
As for the rename stuff, I'm sure there is a better way that what I thought up, but here it is:
Make an executable rename.sh with the following in it:
#!/bin/sh
new=`echo $1 | sed -e 'y/ /_/' -e 'y/,/-/'`
if [ "$1 " = "$new " ]; then
exit;
fi
mv "$*" "$new"
Edit the 'y/ /_/' and 'y/,/-/' to whatever you want, and then run the famous find command again:
find . -exec ./rename.sh {} ;
Here it will replace all spaces to '_' and all ',' to '-'.
Offline
have you tested it?
At first glance I can see it borking..even if you use -depth arg to find..
find will return..
/path/with a/space in it/
/path/with a/space in it/further down/
it will try to rename the first one as follows..
mv /path/with a/space in it/ /path/with_a/space_in_it/
which will not work.
you could try using the above, and find, to work only with a depth of 1. then you have to somehow traverse the tree (breadth first or depth first), running the command at each level.
or..something.
"Be conservative in what you send; be liberal in what you accept." -- Postel's Law
"tacos" -- Cactus' Law
"t̥͍͎̪̪͗a̴̻̩͈͚ͨc̠o̩̙͈ͫͅs͙͎̙͊ ͔͇̫̜t͎̳̀a̜̞̗ͩc̗͍͚o̲̯̿s̖̣̤̙͌ ̖̜̈ț̰̫͓ạ̪͖̳c̲͎͕̰̯̃̈o͉ͅs̪ͪ ̜̻̖̜͕" -- -̖͚̫̙̓-̺̠͇ͤ̃ ̜̪̜ͯZ͔̗̭̞ͪA̝͈̙͖̩L͉̠̺͓G̙̞̦͖O̳̗͍
Offline
I did test it, but not with directies with spaces in them, now you mention it... Though find worked for making dirs executable, which has the same problem, and there it doesn't bork: it first makes the dir executable before entering it. I hope the same will happen with the renaming, as it's exactly the same kind of problem at first glance.
Offline
the problem is you can make a dir executable, but you you weren't changing a name there..
between the first and second renames, the directory can change. ie..
you can chmod /path/with a/space in it/further down/
you cannot just rename /path/with a/space in it/further down/ to /path/with_a/space_in_it/further_down/
and then rename /path/with a/space in it/ somewhere down the line
"Be conservative in what you send; be liberal in what you accept." -- Postel's Law
"tacos" -- Cactus' Law
"t̥͍͎̪̪͗a̴̻̩͈͚ͨc̠o̩̙͈ͫͅs͙͎̙͊ ͔͇̫̜t͎̳̀a̜̞̗ͩc̗͍͚o̲̯̿s̖̣̤̙͌ ̖̜̈ț̰̫͓ạ̪͖̳c̲͎͕̰̯̃̈o͉ͅs̪ͪ ̜̻̖̜͕" -- -̖͚̫̙̓-̺̠͇ͤ̃ ̜̪̜ͯZ͔̗̭̞ͪA̝͈̙͖̩L͉̠̺͓G̙̞̦͖O̳̗͍
Offline
Yes, but that's the same for unexectuable dirs:
You can't be in ./a/b/ if a/ isn't executable, so if find would go into the dirs first before executing the command then it wouldn't be possible to make all dirs executable with one find command.
Same for spaces, if there is "a a" and "b b", then "a a" will be renamed to "a_a" before find goes into that dir and tries to rename "b b", so the case you mentioned should never happen.
Ok, after testing it my theory seems to be correct, though find isn't smart enough to keep the fd of the dir open and use that, but instead it caches the name and after the rename it complains that the dir isn't there anymore.
So for now "find . -type f -exec ./rename.sh {} ; " should be used to rename only the files, as that work correct, and something else must be used to rename the dirs. Though doing that find command often enough should also work, as it will rename all dirs in one level.
Offline
though find isn't smart enough to keep the fd of the dir open and use that, but instead it caches the name and after the rename it complains that the dir isn't there anymore.
Kinda like I said huh?
"Be conservative in what you send; be liberal in what you accept." -- Postel's Law
"tacos" -- Cactus' Law
"t̥͍͎̪̪͗a̴̻̩͈͚ͨc̠o̩̙͈ͫͅs͙͎̙͊ ͔͇̫̜t͎̳̀a̜̞̗ͩc̗͍͚o̲̯̿s̖̣̤̙͌ ̖̜̈ț̰̫͓ạ̪͖̳c̲͎͕̰̯̃̈o͉ͅs̪ͪ ̜̻̖̜͕" -- -̖͚̫̙̓-̺̠͇ͤ̃ ̜̪̜ͯZ͔̗̭̞ͪA̝͈̙͖̩L͉̠̺͓G̙̞̦͖O̳̗͍
Offline
have you tested it?
At first glance I can see it borking..even if you use -depth arg to find..
find will return../path/with a/space in it/
/path/with a/space in it/further down/it will try to rename the first one as follows..
mv /path/with a/space in it/ /path/with_a/space_in_it/
which will not work.you could try using the above, and find, to work only with a depth of 1. then you have to somehow traverse the tree (breadth first or depth first), running the command at each level.
or..something.
This is why you should all be using zsh
# ls -1df **/*
dir with spaces
dir with spaces/another dir with spaces
dir with spaces/another dir with spaces/file with spaces
# while [ -e **/* * ]; do zmv '(**/)(*) (*)' '$1$2_$3'; done
# ls -1df **/*
dir_with_spaces
dir_with_spaces/another_dir_with_spaces
dir_with_spaces/another_dir_with_spaces/file_with_spaces
- olly
Offline
Kinda like I said huh?
You were close, but still wrong. It renames "./a a" to "./a_a" as it should, and then tries to enter "./a a". Kinda silly, as it's not even down the line, but in the same dir.
As for that zsh script: Nice and all, but more or less the whole point was to avoid a damn loop, no matter if that makes sense or not.
Offline
[..]Thank you. I never realized that Find had an exec switch.[..]
Use it in conjunction with "grep", and you'll never look back as a programmer...
Offline
I don't suppose you have a script handy to traverse a directory tree and replace any spaces with an underscore?
For what's it's worth, I never could get "find" to handle directories with leading dots (hidden files), much less as part of a script handling spaces and capital letters.
I have an old rescursive shell script that I've been using for some time, which gets rid of spaces and capital letters, replacing the spaces with underscore. It works well on ignoring hidden directories too, which I couldn't get to work properly with "find" and the "-prune" option. Anyway, I recently converted everything on my drives to get rid of capital letters and spaces. If you want the script, I'll email it to you or get it to you by another means.
It's about 2k and has some nice output. You can start from any top level directory, and it will traverse all subdirectories automatically, except for the hidden ones, replacing spaces and capital letters along the way. It highlights only those files/subs which were changed, and then gives you a status output of what it did. Just "pm" me if you're interested.
Offline
Pages: 1