ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I've wanted to write a script like this for a while, but I always get stuck. Lets say I have an insecured web directory or something, and all the files have way more permissions then they should have. And say the directories can run very deep on the webserver, like up to 9 subdirectories containing web files.
I want to write a script that starts at the current directory (in this case, /usr/local/apache/htdocs), then goes through and gives the proper chmod permissions based on what type of file something is. If its a directory, I want to execute `chmod 711 $file`, and recurse into the directory and test everything again. If its a file I want to execute a `chmod 644 $file` and leave it like so.
I think I need some sort of callback function. I can't use chmod -R by the way, because that will give the same permissions to EVERYTHING, and I want more control than that.
If I just needed to secure a top-level directory, I would do it like this:
Code:
#!/bin/bash
for file in *
do
if [ -f "$file" ];
then
chmod 644 $file
else
if [ -d "$file" ];
then
chmod 711 $file
fi
fi
done
That works (at least I'm pretty sure, I wrote a very similiar script before, my syntax could be off on the if/else stuff). Can anyone point me in the right direction?
#!/bin/bash
for file in *
do
if [ -f "$file" ];
then
chmod 644 $file
else
if [ -d "$file" ];
then
chmod 711 $file
fi
fi
done
That works (at least I'm pretty sure, I wrote a very similiar script before, my syntax could be off on the if/else stuff). Can anyone point me in the right direction?
Thanks.
While Tink's suggestion above is good, if you still want more control, just change your script like so:
Code:
#!/bin/bash
MYDIR="."
if [ -n "$1" ]
then MYDIR=$1
fi
for file in *
do
if [ -f "$file" ];
then
chmod 644 $file
else
if [ -d "$file" ];
then
chmod 711 $file
$0 $MYDIR/$file
fi
fi
done
The recursion in my solution comes from two parts...
1) The script now takes an argument that is the name of the directory to be processed. If no directory is specified, it makes it "." by default.
2) When encountering a directory, the script calls itself with that directory as an argument.
Admittedly, there was one small error in my script, which is corrected below.
Code:
#!/bin/bash
MYDIR="."
if [ -n "$1" ]
then MYDIR=$1
fi
for file in $MYDIR/*
do
if [ -f "$file" ]
then
chmod 644 $file
elif [ -d "$file" ]
then
chmod 711 $file
$0 $MYDIR/$file
fi
done
#!/bin/bash
find -type d -exec chmod 711 {} \;
find -type f -exec chmod 664 {} \;
Cheers,
Tink
Wow, very nice, I always seem to forget about find! Thanks, I'll be using that alot now.
Quote:
Originally posted by archtoad6
lowpro2k3,
Your double 'fi' bothers me, the following structure works just as well & is a bit cleaner:
Code:
#!/bin/bash
for file in *
do
if [ -f "$file" ];
then
echo "file: $file"
elif [ -d "$file" ];
then
echo " dir: $file"
fi
done
(I changed your chmod's to echo's for testing purposes.)
Thanks, I almost never program in bash and I did a _quick_ search through the bash programming guide and didn't see the 'elif' structure. Much cleaner.
Quote:
Originally posted by Matir
The recursion in my solution comes from two parts...
1) The script now takes an argument that is the name of the directory to be processed. If no directory is specified, it makes it "." by default.
2) When encountering a directory, the script calls itself with that directory as an argument.
Admittedly, there was one small error in my script, which is corrected below.
Code:
#!/bin/bash
MYDIR="."
if [ -n "$1" ]
then MYDIR=$1
fi
for file in $MYDIR/*
do
if [ -f "$file" ]
then
chmod 644 $file
elif [ -d "$file" ]
then
chmod 711 $file
$0 $MYDIR/$file
fi
done
I haven't had a chance to run the script yet, but I think thats exactly what I'm looking for. I forgot the '$0' was the name of the script in bash, very nice.
Quick question, if a top level directory (say /usr/local/apache/htdocs) had multiple directories in it, would that script recurse through all of them? I seem to think with my limited recursion knowledge it would pick one 'path' down a directory tree, but I have a feeling I'm missing something. When I get on a linux system later today I'll test it heavily, replacing 'chmod's with 'echo's and see what happens. But if that works as I hoped, its immediately going in all the /usr/local/sbin folders on every box I manage
Thanks for your help guys, every solution helped me so much.
Of course, Humble Programmer (tm), that I am; I still like my "Alexandrine" approach for its speed & simplicity, in spite of the brute force aspect of it -- changing everything & fixing the deliberate mistakes.
Originally posted by lowpro2k3
I haven't had a chance to run the script yet, but I think thats exactly what I'm looking for. I forgot the '$0' was the name of the script in bash, very nice.
Quick question, if a top level directory (say /usr/local/apache/htdocs) had multiple directories in it, would that script recurse through all of them? I seem to think with my limited recursion knowledge it would pick one 'path' down a directory tree, but I have a feeling I'm missing something. When I get on a linux system later today I'll test it heavily, replacing 'chmod's with 'echo's and see what happens. But if that works as I hoped, its immediately going in all the /usr/local/sbin folders on every box I manage
Thanks for your help guys, every solution helped me so much.
I actually found one additional bug, corrected below. I've also enclosed the output of a test run on one of my directories (new source tree for something I'm writing).
Code:
#!/bin/bash
MYDIR="."
if [ -n "$1" ]
then MYDIR=$1
fi
for file in $MYDIR/*
do
if [ -f "$file" ]
then
echo chmod 644 $file
elif [ -d "$file" ]
then
echo chmod 711 $file
$0 $file
fi
done
Delete the "echo" before each chmod when you are satisfied with its function.
As you can see, it does cycle through each subdirectory and handle each of them. After the recursive call ($0 $file) it returns to the parent process to move on to the next $file.
#!/bin/bash
E='echo'
# uncomment next line when you are satisfied w/ the output
#E=':'
MYDIR="."
if [ -n "$1" ]
then MYDIR=$1
fi
for file in $MYDIR/*
do
if [ -f "$file" ]
then
$E chmod 644 $file
elif [ -d "$file" ]
then
$E chmod 711 $file
$0 $file
fi
done
I have used the tecnique before, just hope I got the details right.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.