Jeff
Jeff

Reputation: 4003

bash loop to change permissions

I'm trying to change all the permissions for the files in my ~/Documents folder and I thought the following little loop would work, but it doesn't seem to be working. Can anyone help me? Here's the loop:

files=~/Documents/*
for $file in $files {
   chmod 755 $file }

I'm trying to write this directly into the bash command line gives me the following error:

-bash: syntax error near unexpected token `chmod'

thanks for your help/advice

Upvotes: 2

Views: 8751

Answers (4)

another.anon.coward
another.anon.coward

Reputation: 11395

The loop should be :

for file in $files
do
   test -f "$file" && chmod 755 "$file"
done  

Please note that you are relying on globbing when you say files=~/Documents/* which will include the directories under ~/Documents as well, thus using the loop will change permissions of the directories as well. You can add a simple test to make sure that you update only the permission of files. Also please note that globbing can be turned off with set -f in which case files will have value of just <HOME_DIR>/* which maynot be a filename; which also will not serve your purpose.

More importantly, as pointed by ghoti in the comments it is not a good idea to rely on globbing. When you make use of globbing the filenames with hypens can have undefined behaviour & filenames with semi-colons can cause security vulnerabilities. Apart for security vulnerabilities associated with globbing there are some common pitfalls associated with it as well. Please take a look at the answer provided by ghoti which highlights some of risks involved with your current operations.

You could use find as well (This will recursive set for all the files):
find ~/Documents/ -type f -exec chmod 755 {} \;
For setting permissions only for the files under ~/Documents/ you can make use of -maxdepth option as such:
find ~/Documents/ -maxdepth 1 -type f -exec chmod 755 {} \;

Hope this helps!

Upvotes: 2

ghoti
ghoti

Reputation: 46856

There are risks in making your documents executable. I recommend against it unless you know exactly what you're doing.

I'm going to take a wild guess that you don't really want to make all your Documents folder executable, and what you're really trying to do is standardize on user-writable everyone-else-readable permission for everything in that folder.

Note that (as someone mentioned in another answer) the chmod command has its own "recursive" option, -R. Note also that you can use "symbolic" permissions with chmod, you're not stuck with octal-only. So:

chmod -R go+r-wx ~/Documents/

will add Read and remove Write and eXecute functions from everything in and under ~/Documents/.

Note that this will make subdirectories readable, but will not provide access to the files within them (because that's what the executable bit on a directory does). So you may want to use TWO commands:

find ~/Documents/ -type d -exec chmod 755 {} \;
find ~/Documents/ -type f -exec chmod 644 {} \;

The first line only runs chmod on directories, making them both readable and accessible. The second line affects only your files, making them readable by the world.

Upvotes: 5

Thor
Thor

Reputation: 47169

Why not:

chmod -R 755 ~/Documents

Upvotes: 1

l&#39;L&#39;l
l&#39;L&#39;l

Reputation: 47209

Try

find . -exec chmod 755 {} +\;

or

find . -type f -exec chmod 755 {} +\;

Upvotes: 3

Related Questions