Nested If statement within Do / Done

Hi all!
I'm really hoping you can help me out here; now i have searched and searched and have at least worked out that you can't have a nested if statement with a 'done' in it (as i have) as you're killing the parent before the child.

So here's what i have, and here's hoping someone can help me think of a work around! FYI, i'm using bash on a custom linux build, fairly standard based around red hat i believe(?)

The script is to find all attached USB devices, and copy a folders contents to it. The issue is within the variable check at the start, and the two unmounting after replication parts.

Theres a few other parts later on which i haven't posted which have a similar issue- so any ideas would be great! :slight_smile:

# Assigning Drive variables and locating available disks.
alldrives=$(df -h | grep sda | awk '{print$1}' | cut -c1-8)
d1=$(echo $alldrives | awk '{print$1}')
d2=$(echo $alldrives | awk '{print$2}')
d3=$(echo $alldrives | awk '{print$3}')
d4=$(echo $alldrives | awk '{print$4}')
d5=$(echo $alldrives | awk '{print$5}')
d6=$(echo $alldrives | awk '{print$6}')
d7=$(echo $alldrives | awk '{print$7}')
d8=$(echo $alldrives | awk '{print$8}')
d9=$(echo $alldrives | awk '{print$9}')
d10=$(echo $alldrives | awk '{print$10}')

for i in $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d10
do
 
if [[ -z $i ]]
then
echo "Variable blank, moving to next"
done
fi
 
#CHECK FOR MOUNTABLE DRIVE, MAKE DIR FOR IT
mkdir /mnt/clone/
if mount "$i""1" /mnt/clone/"$i""1"
then
 
 
# START REPLICATION
echo "BEGINNING RSYNC REPLICATION"
rsync -rtv --progress --modify-window=1 --exclude=LOCAL.CFG /usr/local/FOLDER1 /mnt/clone/"$i""1"/usr/local/FOLDER1
echo
 
 
# UNMOUNT AFTER REPLICATION
if umount /mnt/clone/"$i""1"
then
echo "Unmounted Successfully. Copying Complete."
 
done
else
 
 
# FORCE IF UNABLE TO UNMOUNT
echo "Forcing unmount..."
sync
sleep 15
cd /
umount -f /mnt/clone/"$i""1"
done
fi
 
fi

Small wonder you're having problems with this. I can't even understand why it compiles, maybe it's a bug, but I can't image that using "done" inside if-statements to close the surrounding loop is legal.

With loops, use either "break" to break out of the loop, or "continue" to start the next iteration.

Aside from that, if the drives in $alldrives are space seperated, you can rewrite your loop to

for i in $alldrives
do
    ....

Future debugging tips:

  • set -x shows a nice trace on stderr of what is done
  • the -n switch to ksh/bash does a syntax check without running the script

---------- Post updated at 14:56 ---------- Previous update was at 14:52 ----------

Just verfied on Linux using your snipped of code:

$ bash -n test.sh
test.sh: line 20: syntax error near unexpected token `done'
test.sh: line 20: `done'
$ ksh -n test.sh
test.sh: syntax error at line 20: `done' unexpected

Replacing your "done"s with "continue"s:

$ ksh -n test.sh
$ bash -n test.sh

May i just say you are a legend!
I wasn't aware of the break/continue commands and that has sorted it straight out, replaced all dones (except for final, out of nest, one!) with continues and voila.

Thanks again for saving me hours of headache,
Darren.