MrTunaDeluxe
MrTunaDeluxe

Reputation: 152

Bash: syntax error near unexpected token `else'

I have the following code that checks whether either of two input args are supplied, and depending on their existance runs a certain piece of code. I'm running into syntax errors in my if statements however, because I'm getting an unexpected token `else' error

if [ -z "${4}" ] || [ -z "${5}" ]
then
    echo "Missing index argument(s). Defaulting to entire file."
    cat ${devicesFile} | cut -d "," -f 4 | tr [:upper:] [:lower:] | awk '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' | while read deviceGuid
else
    i1=${4}
    i2=${5}
    head -n ${i1} ${devicesFile} | tail -n ${i2} | cut -d "," -f 4 | tr [:upper:] [:lower:] | awk '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' | while read deviceGuid
fi

Is it an issue with my or condition.? That's the only thing I can really think of. Any help would be greatly appreciated.

//Here's what I had before I tried to add the index parameters, so what HVD said about the broken while makes sense..

cat ${devicesFile}  | cut -d "," -f 4 | tr [:upper:] [:lower:] | awk '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' | while read deviceGuid
do
    # now=`date +"%Y%m%d %H%M%S"`
    currentTime=`date +"%H%M%S"`
    currentHour=`date +"%H"`
    currentDate=`date +"%Y%m%d"`
    # create parent directory
    mkdir -p ${crashlogFolder}/${currentDate}/${currentHour}/${crashCode}/
    # create crash log for device
    touch ${crashlogFolder}/${currentDate}/${currentHour}/${crashCode}/${currentTime}_${deviceGuid}.log
done

Upvotes: 0

Views: 756

Answers (3)

glenn jackman
glenn jackman

Reputation: 246799

This is really a comment on Édouard Lopez's answer: DRY -- pull out all the common code:

if [[ -z "${4}" || -z "${5}" ]]; then
    cat ${devicesFile} 
else
    head -n ${i1} ${devicesFile} | tail -n ${i2}
fi |
  cut -d "," -f 4 | 
  tr [:upper:] [:lower:] | 
  awk -F, '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' |
  while read deviceGuid; do 
    : 
  done

Note to MrTunaDeluxe: ${var} is different from "$var" -- you should prefer the latter. The first form is required for array element expansion, the various parameter substitutions, and also to disambiguate the variable from surrounding text (e.g. echo "${var}text"), but just using braces will not prevent word splitting or filename expansions.

Upvotes: 3

Édouard Lopez
Édouard Lopez

Reputation: 43391

You're lacking a body to your while block, it should have the form while <condition>; do <actions>; done

if [[ -z "${4}" || -z "${5}" ]]; then
    # …
    cat ${devicesFile} \
    | … \
    | while read deviceGuid; do echo $deviceGuid; done
else
    # …
    head -n ${i1} ${devicesFile} \
    | … \
    | while read deviceGuid; do echo $deviceGuid; done
fi

Explaination

  1. used bash test [[ … ]] so you can use the boolean OR inside as [[ … || … ]], discard if you need portability;
  2. replaced some of your command by just for clarity
  3. escaped newline, \ at the end of line (no spaces must follow), to get a clearer script
  4. added missing block with dummy echo $deviceGuid command.

Upvotes: 4

user743382
user743382

Reputation:

You cannot mix control structures like that. If you originally had

a | while b
do
  c
done

and now you want a to be customisable, you cannot do

if d
then
  e | while b
else
  f | while b
fi
do
  c
done

Shells just don't work like that. (Nor do most other languages.) while b; do c; done was a single statement, and cannot be broken up like that.

Instead, you should change it to

if d
then
  e
else
  f
fi | while b
do
  c
done

The whole if d; then e; else f; fi is a single statement, and its output, regardless of which of the commands it comes from, will be piped to the while statement.

Upvotes: 5

Related Questions