Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Why would following script not execute, but give a syntax error of else:

LOGS3_DIR=~/logs
if [ -d "$LOGS3_DIR" ]; then
 cd
 cd "$LOGS3_DIR"
 echo "$LOGS3_DIR"
 for filename in `find "." -mtime 1 -type f`
  do
  if lsof "$filename" > /dev/null
  then
    # file is open
  else
    echo "deleting $filename"
    rm "$filename"
  fi
 done
fi
share|improve this question

4 Answers 4

up vote 11 down vote accepted

Don't use command substitution on the output of find. Here, everything can be done with find.

find . -mtime 1 -type f ! -exec lsof -t {} \; -exec rm -f {} \; > /dev/null

With GNU find, you can use -delete instead of -exec rm....

share|improve this answer
4  
While this is a much better way to do what @Novice User is attempting, it doesn't answer the question at all. –  Chris J. Breisch Jun 2 at 18:49
    
While -exec is often useful, as is xargs, sometimes a shell loop is needed. In which case a while read name loop is the preferred option (in bash with GNU find you can use the -0 option for both; portably you have to give up on newline). –  Jan Hudec Jun 3 at 8:06
    
@JanHudec, There are ways portably. -print0 is -exec printf '%s\0' {} + (but portably you can't deal with that output except if you want to consider perl), and with find .//. and some post-processing, you can escape the newlines for xargs. Note that it's not a while read, it's while IFS= read -r. –  Stéphane Chazelas Jun 3 at 8:29

It seems that you want to do a no-op if the file is open so you should add a :, which is a null command in bash:

if lsof "$filename" > /dev/null
then
  # file is open
  :
else
  echo "deleting $filename"
  rm "$filename"
fi

If you don't use :, bash can not parse you code, and will show error like bash: syntax error near unexpected token 'else'.

share|improve this answer

Another alternative: reverse your logic.

if ! lsof "$filename" >/dev/null;then
    echo "deleting $filename"
    rm "$filename"
fi
share|improve this answer
    
Thanks. This is good idea. –  Novice User Jun 1 at 20:11

TL;DR

None of the other answers actually addresses your original question of why the command gives a syntax error. This is caused by a missing command between then and else.

A Missing Command

Your original code looks like this:

if lsof "$filename" > /dev/null
then
  # file is open
else
  echo "deleting $filename"
  rm "$filename"
fi

The problem is that you have a comment between then and else, but the comment isn't treated as a command. In short, you could rewrite the problem you have (structurally speaking) as follows:

$ if true; then else echo; fi
bash: syntax error near unexpected token `else'

Fix Your Syntax with a Bourne Builtin

You can fix this problem by placing actual commands before else, but a comment by itself won't do. The if-then section can't be empty; if you want a placeholder, you can use the colon builtin. For example:

$ if true; then :; else echo; fi

Simply placing : into the section between then and else will fix the syntax error you are experiencing.

share|improve this answer
1  
Gnouc answer, which is also the most upvoted one, is already adressing the original question. –  jlliagre Jun 2 at 1:19
    
Only answer to address the syntax error. FWIW, you can reproduce a similar error with a sole semi-colon at the beginning of a line. This will give a strong hint. $ ; -bash: syntax error near unexpected token ';' –  Matthew Hannigan Jun 5 at 10:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.