Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Redhat 5.3 Enterprise

The following Shell script is used to check and see if a backup directry is named "ll_backup", then changes it to equal the content of a file RESULT.VAR. The result.var file is copied for log purposes to another directory. I had this working in a test enviorenment but in production it throughs a weird error that I can't for the life of me figure out!

SCRIPT:

#!/bin/bash
#!/bin/cat
# Restores original directory name for next LogLogic Update
#TCJ 6/1/09
declare RESULT
declare FILE
FILE=result.var
cd /home/nb-backup/backups/nb-st3000/ll_bkup_65.99.220.172/
if [ -d ll_bkup ]
 then
        cat result.var | while IFS=: read RESULT
        mv  "ll_bkup" "$RESULT"
        mv result.var /home/storegrid/scripts/results/result-`date +%y%m%d%s`.var
else
         exit 0
fi
exit 0

RESULT:

nb-script-restorellbackup.sh: line 14: syntax error near unexpected token else' nb-script-restorellbackup.sh: line 14: else'

share|improve this question
    
not even remotely red hat specific: retagged to linux, bash –  wzzrd Jun 20 '09 at 16:46
add comment

3 Answers

up vote 2 down vote accepted

There are a number of problems, ranging from minor to fatal (all of the fatal ones have to do with the "cat...while...read" line). Let me go through them in order:

  • As Dennis Williamson pointed out, the "#!/bin/cat" and "declare..." lines don't do anything.
  • You set FILE to result.var near the top, but then never use this variable. Assuming it's intended to allow you to change the filename in just one place, you should replace all other references to result.var with "$FILE"
  • The while statement needs a "do...done" - or rather, it would if you actually needed the while statement in the first place. Since you're only reading one RESULT from the file, you don't need a loop.
  • Since the "read RESULT" is part of a pipeline, it runs in a subshell, and the value of RESULT it sets is lost when that subshell exits. You could fix this by using something like 'read RESULT <"$FILE"'.
  • What's the "IFS=:" bit there for? It sets the internal field separator to ":" for the duration of the read command, but since you're only reading one field (RESULT), the only thing it does is to trim leading or trailing colons from what's read from result.var. If you meant to ignore everything after a colon (i.e. only use the first colon-delimited field from result.var), you should use "IFS=: read RESULT IGNOREDJUNK" instead.
  • Unless you're actually trying to trim/parse the contents of result.var, or need to use it several times, you don't need to read it into a variable at all; just use 'mv "ll_bkup" "$(cat "$FILE")"'. But I claim you want to use it again (see below).
  • The script is rather fragile in the sense that it doesn't check to make sure result.var exists (and since the script moves that file, if run twice in a row it's guaranteed to fail the second time); similarly, it doesn't check if "$RESULT" already exists before trying to rename ll_bkup to it, leading to potentially unpredictable results.
  • Speaking of which, your description says result.var gets copied, but the actual code moves it. Which is the intended behavior?
  • Finally, the "else... exit 0" section does nothing that the "exit 0" at the end isn't about to do anyway.

Gripe, gripe, gripe... anyway, here's my proposed rewrite:

#!/bin/bash
# Restores original directory name for next LogLogic Update
#TCJ 6/1/09
FILE=result.var
cd /home/nb-backup/backups/nb-st3000/ll_bkup_65.99.220.172/
if [ -d ll_bkup -a -f "$FILE" ]; then
    read RESULT <"$FILE"
    if [ ! -e "$RESULT" ]; then
        mv  "ll_bkup" "$RESULT"
        mv "$FILE" /home/storegrid/scripts/results/result-`date +%y%m%d%s`.var
    fi
fi
exit 0
share|improve this answer
    
You, sir, are an evil genius. Thanks for the great feedback, and your script worked untouched! –  TrevJen Jun 21 '09 at 18:15
add comment

You need to change the line to look like this:

cat result.var | while IFS=:; do read RESULT; done

This cat and read looks like to me that it sets $RESULT equal to the first word of the last line of the contents of the file "result.var"

and remove this line:

#!/bin/cat

since it's not doing anything.

You don't really need to use declare in this situation.

Use $() around your date command. It's more readable and can be more easily nested, if necessary.

share|improve this answer
    
Why have the while loop at all? tail -1 result.var | IFS=: read RESULT –  pgs Jun 20 '09 at 16:39
    
@pgs - if that's what is really intended, then yes. –  Dennis Williamson Jun 20 '09 at 16:46
add comment

What's going on with the while loop? It needs do ... done somewhere.

Here's some reference material for you:

share|improve this answer
add comment

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.