tags:

views:

522

answers:

3

Good afternoon, I have a question about a script I am having problems with. I did something similar a couple of years ago and based this on that (which was on a different server). I need to run the script from a directory that has a number of directories in it and for each directory have it create a directory and change it's ownership. The script is:

#!/bin/bash
for DIR in *;
do 
mkdir $DIR/photos2; 
chown apache:apache $DIR/photos2; 
chmod 777 $DIR/photos2; 
done

When trying to run I get - syntax error near unexpected token `do'

I'm sure it is something silly I'm missing, any help would be appreciated.

+2  A: 

You probably want to do something like this:

#!/bin/bash
for DIR in *; do
    if [ -d "$DIR" ]; then 
        mkdir "$DIR/photos2"
        chown apache:apache "$DIR/photos2"
        chmod 777 "$DIR/photos2"
    fi
done
  • The error with "do" is because bash is line-oriented and expects the "do" to be on the same line. You can, of course, put a \ at the end of the line instead. EDIT: this is not correct. A not-so-educated guess, presumably.
  • The semicolons are not necessary when commands are on different lines.
  • Quotes around $DIR is necessary in case you have spaces in any filenames.
JesperE
IF you choose to keep the 'do' on the same line as the 'for', you need a ';'. I have not seen other constraints around this with bash.
nik
None of the other problems listed here would invoke a syntax error near the 'do'.
nik
You can leave off the if statement if your for looks like "for DIR in */" (note the added slash).
Dennis Williamson
+1  A: 

either

for DIR in *
do

or

for DIR in *; do
n-alexander
I think both these forms will work as well in bash.
nik
Semicolon at the end of a line is allowed. The form in the question also works.
Rob Kennedy
+2  A: 

I have seen funny things happen with scripts when they were in DOS format.
Are you by any chance writing code on a Windows platform and trying to run it from a bash shell somewhere else?

On the bash shell, there will usually be a command called dos2unix, if you find it, try running,

dos2unix scriptname

and, then run the script again.


One more check, are you sure you have an error saying "unexpected token 'do'" and not 'done'?
Anyways, I suggest you read up for loop at the bash guide


Meanwhile, this should do your work from the base directory (while your filenames do not have SPACE characters).

#!/bin/bash
for DIR in $(find . -type d);
do 
    mkdir $DIR/photos2; 
    chown apache:apache $DIR/photos2; 
    chmod 777 $DIR/photos2; 
done
nik
I think you're right. If I have Unix line ends on the first two lines (shebang and for), and a Windows line end on the third line (do), I get the same error the asker reports. I'm running Bash 4 on Solaris.
Rob Kennedy
You very well might want a "-maxdepth 1" after the "." in your find command. However, you don't need the find if your for looks like "for DIR in */" (note the added slash).
Dennis Williamson
@Dennis, That is quite correct if he wants to limit to only one level of directories from the reference base directory. However, the questions did not suggest that particularly.
nik