![如何在 bash 脚本中创建循环](https://linux22.com/image/37914/%E5%A6%82%E4%BD%95%E5%9C%A8%20bash%20%E8%84%9A%E6%9C%AC%E4%B8%AD%E5%88%9B%E5%BB%BA%E5%BE%AA%E7%8E%AF.png)
我写了以下脚本。它由 udev 调用。当我插入外部 USB 硬盘驱动器时,脚本会检查该卷是否由 truecrypt 挂载,如果不是,则会挂载它;如果安装了它,它会将某个文件夹中的所有文件复制到外部硬盘。复制完成后,它会检查该卷是否仍由 truecrypt 挂载。如果是,它会尝试卸载它,如果不是,它会向我发送一封电子邮件。
我想要实现的是一种递归检查卷是否已安装的方法,这意味着如果该卷仍然已安装,则应尝试卸载它,依此类推,直到它检查该卷未安装并发送给我一封电子邮件。
更清楚地说:在 Windows cmd 中我会使用 GOTO 标签,但 linux bash 没有 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
答案1
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
循环while
将永远继续执行,直到break
语句运行完毕。如果[ -f $file ]
计算结果为 true,则其代码块将运行并break
退出循环。否则$sendemail
将触发,然后sleep n
循环将重新开始
答案2
while [[ -f $file ]]; do
truecrypt -d /dev/sdj1
sleep 10 # pause for 10 seconds
done
$sendanemail
考虑到您的$subject
消息是“已完成”,我想您只想发送一封电子邮件。
此版本将反复尝试卸载您的 truecrypt 驱动器,直到成功为止,然后发送一封电子邮件。
如果USB驱动器无法卸载,那么就会出现无限循环。另一种方法是向脚本添加超时。
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
答案3
好吧,对于任何需要它的人来说,这是我的最终脚本,看起来它很有魅力。
#!/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