0

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'

1
  • not even remotely red hat specific: retagged to linux, bash Commented Jun 20, 2009 at 16:46

3 Answers 3

2

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 
1
  • You, sir, are an evil genius. Thanks for the great feedback, and your script worked untouched! Commented Jun 21, 2009 at 18:15
1

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

Here's some reference material for you:

1

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.

2
  • Why have the while loop at all? tail -1 result.var | IFS=: read RESULT Commented Jun 20, 2009 at 16:39
  • @pgs - if that's what is really intended, then yes. Commented Jun 20, 2009 at 16:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.