2

I wrote the following script. It is invoked by udev. When I plug my external USB hard drive the script checks if the volume is mounted by truecrypt, if it is not, it mounts it; if it is mounted it copies all files from a certain folder to the external hard disk. When the copy is done, it checks if the volume is still mounted by truecrypt. If it is, it tries to dismount it, if it is not, it sends me an email.

What I would like to achieve is a way to check recursively if the volume is mounted or not, this means that if the volume is still mounted it should try to dimount it and so on, until it checks that the volume is not mounted and sends me an email.

To be clearer: in windows cmd I would use GOTO label, but linux bash doesn't have GOTO.

#!/bin/sh
# 
############ Parameters ############
from="from"
dest="dest"
smtp="smtp"
username="username"
pass="pass"
message="Sync to hard disk 1TB completed. You shall now remove the external hard drive."
subject="Sync to hard disk 1TB completed."
file="/media/truecrypt2/sync/dummy.file"
sendanemail="sendEmail -f $from -t $dest -u $subject -s $smtp -xu $username -xp $pass -m $message"
############ End Parameters ############

sleep 4
touch $file

if [ -f $file ];
then
   cp /storage/sdf1/folder/*.txt /media/truecrypt2/sync/ -n -r
   cp /storage/sdf1/folder/*.jpg /media/truecrypt2/sync/ -n -r
else
   echo "truecryptpassword" | truecrypt /dev/sdj1 /media/truecrypt2 -t -k="" --protect-hidden=no -p=""
   cp /storage/sdf1/folder/*.txt /media/truecrypt2/sync/ -n -r
   cp /storage/sdf1/folder/*.jpg /media/truecrypt2/sync/ -n -r
fi

sleep 4

if [ -f $file ]
then
   truecrypt -d /dev/sdj1
   if [ -f $file ]
   then
     truecrypt -d /dev/sdj1
   else
     $sendanemail
   fi
else
   $sendanemail
fi
2
while true; do
   if [ -f $file ]; then
       truecrypt -d /dev/sdj1
       break
   fi
       $sendanemail
       sleep n # change n to number of seconds to pause 
done

The while loop will continue to execute forever until the break statement is ran. If [ -f $file ] evaluates to true then it's code block will run and break will exit the loop. Otherwise $sendemail will fire, then sleep n and the loop will start over

  • @user3161330 you're welcome, if that works for you then go ahead and accept the answer so the question gets closed – Creek Jun 10 '14 at 22:21
  • I will try ASAP! – giovi321 Jun 11 '14 at 17:59
  • Is there a reason why if I use find /storage/sdf1/folder/ -name '*.txt' -exec cp -n -r '{}' /media/truecrypt2/sync/ \; instead of cp /storage/sdf1/folder/*.txt /media/truecrypt2/sync/ -n -r the whole script is not working? – giovi321 Jun 11 '14 at 18:05
  • @user3161330 your cp command is only searching in /storage/sdf1/folder/ where find is searching through every subdirectory of /storage/sdf1/folder/ as well. Without seeing the error message I can't say exactly why it's not working, but my guess would be permissions – Creek Jun 11 '14 at 18:58
  • I forgot to put a ; in my original code.. – giovi321 Jun 12 '14 at 13:57
1
while [[ -f $file ]]; do
    truecrypt -d /dev/sdj1
    sleep 10    # pause for 10 seconds
done
$sendanemail

Considering your $subject is a "Completed" message, I imagine you only want a single email sent.

This version will repeatedly try to unmount your truecrypt drive until it succeeds, then send one email.

If the usb drive fails to unmount, then you will have an infinite loop. An alternative to is to add a timeout to the script.

attempts=5
while [[ -f $file ]]; do
    truecrypt -d /dev/sdj1
    sleep 10

    attempts=$(($attempts - 1))
    if [[ $attempts -eq 0 ]]; then
        subject="Failed to unmount /dev/sdj1"
        message="Cannot umount external hard disk.  Please verify sync to hard disk 1TB completed and manually unmount the external hard disk before removal."
        sendanemail="sendEmail -f $from -t $dest -u $subject -s $smtp -xu $username -xp $pass -m $message"
        break
    fi

    # attempts=$(($attempts - 1))  # this adds an extra attempt
done
$sendanmail
  • This is very nice, but it does not subtract 1 from $attempts – giovi321 Jun 12 '14 at 13:23
  • Ok, I have been able to fix it using let. Check my answer. – giovi321 Jun 12 '14 at 13:50
  • I was missing a $ on the $(()) arithmetic expansion operator, which is equivalent to let according to man bash. So either way works. – Justin C Jun 12 '14 at 15:51
  • Also, with regards to your answer, @giovi321, your decrement cannot be inside the if statement. $attempts is 3 and will never reach 0 which is required to pass the condition of the if statement. Commented here since I don't have 50 rep to comment directly to your answer. – Justin C Jun 12 '14 at 15:58
  • @giovi321, good place, that ensures you only have 3 attempts instead of an extra attempt like mine. Also, unless you want $sendandemail to run on each attempt, you may want to use [[ ! -f $file ]] && $sendanemail to ensure it only runs once before the loop quits. – Justin C Jun 12 '14 at 16:25
1

Ok, for anybody who needs it, this is my final script, and it looks like it's working like a charm.

#!/bin/sh
#
# Comments....

############ Parameters ############
attempts="3"
from="from@example.com"
to="to@example.com"
smtp="smtp.example.com:25"
username="from@example.com"
pass="emailpass"
message="Sync to hard disk 1TB completed. You shall now remove the external hard drive."
subject="SRVR: Sync to hard disk 1TB completed."
file="/media/truecrypt2/sync/dummy.file"
sendanemail="sendemail -f $from -t $to -u $subject -s $smtp -xu $username -xp $pass -m $message"
subjectfail="Unable to umount external hard disk."
messagefail="Unable to dismount external hard disk after $attempts attempts. Please check it."
sendanemailfail="sendemail -f $from -t $to -u $subjectfail -s $smtp -xu $username -xp $pass -m $messagefail"
############ End Parameters ############

sleep 4

touch $file

if [ -f $file ];
then
   cp /storage/sdf1/folder/*.txt /media/truecrypt2/sync/ -n -r
   cp /storage/sdf1/folder/*.jpg /media/truecrypt2/sync/ -n -r
else
   echo "my truecrypt password" | truecrypt /dev/sdj1 /media/truecrypt2 -t -k="" --protect-hidden=no -p=""
   cp /storage/sdf1/folder/*.txt /media/truecrypt2/sync/ -n -r
   cp /storage/sdf1/folder/*.jpg /media/truecrypt2/sync/ -n -r
fi

sleep 0

while [ -f $file ]; do
    truecrypt -d /dev/sdj1
    sleep 5

    attempts=$(($attempts - 1))         # decrement timeout counter.
    if [ $attempts -eq 0 ]; then
      $sendanemailfail
      break
    fi

    [[ ! -f $file ]] && $sendanemail    # only send email once when `truecrypt -d` succeeds.
done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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