BASH:为每个循环迭代重定向日志dillema /重复重定向

时间:2014-07-23 16:15:05

标签: linux bash redirect backup stdout

我有一个重定向困境,我无法通过我在CentOS 6.4中开发的bash备份脚本来解决这个问题。我想将所有输出重定向到两个单独的文件:一个tmp和一个永久文件。该脚本循环遍历外部源列表,我希望tmp日志文件特定于源,以便我可以发送电子邮件,如果该特定源包含该日志的错误(并反过来删除tmp,如果备份完成且没有错误)。

我使用exec开发我的输出:

exec > >(tee -a ${templog} /var/log/rob/rob.log) 2>&1

如果我放在脚本的顶部,但是这里变量尚未定义,那么这是有效的,所以我不能做特定于源的日志。

如果我将它放在while循环中,它会抓取变量,但会写出由循环的总迭代次数确定的每一行的副本;对于下面的示例,我有四个迭代的源,所以我得到每个源的输出一式四份:

-S-07/11/14 09:15:35 ROB-Source Process for cc2-gamma has started-S-
-S-07/11/14 09:15:35 ROB-Source Process for cc2-gamma has started-S-
-S-07/11/14 09:15:35 ROB-Source Process for cc2-gamma has started-S-
-S-07/11/14 09:15:35 ROB-Source Process for cc2-gamma has started-S-
Share cc2-gamma is not Mounted. Try 1 of 5 to mount...
Share cc2-gamma is not Mounted. Try 1 of 5 to mount...
Share cc2-gamma is not Mounted. Try 1 of 5 to mount...
Share cc2-gamma is not Mounted. Try 1 of 5 to mount...

是否有不同的方法来在循环中发出输出以防止这种情况(当然不触及每一行)?或者我的循环中有什么东西腐烂了,我没有看到?这是整个剧本。请原谅一塌糊涂的风格..我显然没有完成。我没有包含config.conf和备份源文件,因为它们不会影响输出。如果需要,请告诉我。感谢。

#!/bin/bash
#V.2014.0723 - Radation Oncology Backup script
#declarations
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/rob
source /rob/conf/config.conf
while read smbdir 'smbpath' exclfile drive foldername; do
#loop declarations
mountedfile=/rob/${smbdir}.MOUNTED
runningfile=/rob/${smbdir}.RUNNING
lastrunfile=/rob/${smbdir}_${foldername}.LASTRUN
templog=/rob/${smbdir}_${foldername}.TMPLOG
errorfile=/rob/${smbdir}_${foldername}.HAD_ERRORS
backupfile=/rob/${baname:0:3}_rtbackup.sql.bz2      # for the -l seccton below -- sql backup of backup.sql
#exec > >(tee -a ${templog} /var/log/rob/rob.log) 2>&1
### SOURCE BACKUP ##############################################################################################
if [ "$1" == "-s" ]
then
    exec > >(tee -a /var/log/rob/rob.log ${templog}) 2>&1
    #Write Source STDOUT and STDERR to both permanent and temporary log file. Must be in loop to use variables.
    #exec > >(tee -a ${templog} /var/log/rob/rob.log) 2>&1
    #exec > >(tee -a /var/log/rob.log ${templog}) 2>
    if [ "${sources_active}" == "1" ]
    then
    echo "-S-$(date "+%m/%d/%y %T") ROB-Source Process for $smbdir has started-S-" 
    # unmount all cifs shares, due to duplicate mounts, write file to prevent concurrentcy 
    umount -a -t cifs > /dev/null
    # The following will test to see if the souce is mounted, and if not, mount it.
    for i in {1..5}
        do
        if mountpoint -q /mnt/${smbdir}/${drive}/${foldername}
        then
        echo "Share ${smbdir} is Mounted." 
        touch $mountedfile
        break
        else
        sleep 2
        echo "Share ${smbdir} is not Mounted. Try $i of 5 to mount..." 
        mkdir -p /mnt/${smbdir}/${drive}/${foldername} > /dev/null 
        mount -t cifs ${smbpath} -o ro,username=<USER>,password=<PW>,workgroup=<DOMAIN> /mnt/${smbdir}/${drive}/${foldername} 
        fi
        done
    # Test to see if above was successful, and if rob is not already running, run the backup.
    if [[ -f ${mountedfile}&& ! -f ${runningfile} ]]
    then
        src="/mnt/${smbdir}/$drive"
        dst="/backup/rob/"
        touch ${runningfile}
        /root/bin/rtbackup -m /mnt -p ${src}/${foldername} -b ${dst} -x @${exclfile}
        if [ "$?" -ne "0" ]; then
            #Errors Running RTBackup
            rm -f ${runningfile} > /dev/null 2>&1
            rm -f ${mountedfile}> /dev/null 2>&1
            echo "$(date "+%m/%d/%y %T") Source Process for ${smbdir} had errors running:-SSS"  
            echo "$errors" >&2
            touch ${errorfile}
            exit 1
    else
    echo "What the  hell is this doing?"
    fi
            #NO Errors Running RTBACKUP
            rm -f ${templog}
            rm -f ${runningfile} > /dev/null 2>&1
            rm -f ${mountedfile} > /dev/null 2>&1
            echo "$(date "+%m/%d/%y %T") Source Process for ${smbdir} did not have any errors"
    else
        #backup will *NOT* run, cleaning up and logging
        rm -f ${mountedfile} > /dev/null 2>&1
        echo "$(date "+%m/%d/%y %T") ${smbdir} could not be mounted, or is already in progress. Backup could not complete." 
        touch ${errorfile}
        tail /var/log/rob/robso.log | mail -s "ROBSO Failed to run for ${smbdir} on ${baname}" ${email}
    fi
    echo "-F-$(date "+%m/%d/%y %T") ROB-Source Process for ${smbdir} has finished-F-" 
    #break
    elif [[ "${sources_active}" == "0"  ]] 
    then
        echo "***$(date "+%m/%d/%y %T") ROB-Source Process for ${smbdir} did not run because the job is not set as active***" 
    #break
    fi
done < /rob/conf/${baname}.conf
if [ $? -eq 10 ]; then exit 0; fi

1 个答案:

答案 0 :(得分:0)

您可以使用花括号来重定向一组命令;正如它在bash manual about command grouping中说的那样,“当命令被分组时,重定向可以应用于整个命令列表”。它的行为或多或少像匿名函数。

{
  command1
  command2
} > >(tee -a ${templog} /var/log/rob/rob.log) 2>&1

如果您愿意,也可以对命名函数执行相同操作,但我不知道将使用哪种环境来扩展重定向。 (如果那么,请编辑这个答案!)

# Untested. This MIGHT work.
your_log_command() {
  command1
  command2
} > >(tee -a $1 /var/log/rob/rob.log) 2>&1

your_log_command $templog
your_log_command $something_else