Como criar um loop no script bash

2

Eu escrevi o seguinte script. É invocado pelo udev. Quando eu conecto meu disco rígido USB externo, o script verifica se o volume está montado por TrueCrypt, se não estiver, monta-o; se estiver montado, copia todos os arquivos de uma determinada pasta para o disco rígido externo. Quando a cópia é concluída, verifica se o volume ainda está montado por TrueCrypt. Se for, ele tenta desmontá-lo, se não for, me envia um email.

O que eu gostaria de conseguir é uma maneira de verificar recursivamente se o volume está montado ou não, isso significa que se o volume ainda estiver montado, ele deve tentar diminuí-lo e assim por diante, até verificar se o volume não está montado e me envia um email.

Para ser mais claro: no windows cmd eu usaria o GOTO label, mas o linux bash não tem 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
    
por giovi321 10.06.2014 / 22:27

3 respostas

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

O loop while continuará sendo executado para sempre até que a instrução break seja executada. Se [ -f $file ] for avaliado como verdadeiro, o bloco de código será executado e break sairá do loop. Caso contrário, $sendemail será disparado, então sleep n e o loop será reiniciado

    
por 10.06.2014 / 22:48
1
while [[ -f $file ]]; do
    truecrypt -d /dev/sdj1
    sleep 10    # pause for 10 seconds
done
$sendanemail

Considerando que sua $subject é uma mensagem "Concluída", imagino que você queira apenas um único e-mail enviado.

Esta versão repetidamente tentará desmontar sua unidade TrueCrypt até que seja bem-sucedida e, em seguida, enviar um e-mail.

Se a unidade USB não for desmontada, você terá um loop infinito. Uma alternativa é adicionar um tempo limite ao 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
    
por 11.06.2014 / 04:37
1

Ok, para quem precisa, este é meu roteiro final e parece que está funcionando como um encanto.

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

############ Parameters ############
attempts="3"
from="[email protected]"
to="[email protected]"
smtp="smtp.example.com:25"
username="[email protected]"
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
    
por 12.06.2014 / 15:51