Bash Variable失去了它的价值 - 奇怪

时间:2011-11-22 02:26:14

标签: bash cron

注意FTP_PUT_RETVAL。有两个echo命令,第一个显示值' 0'。第二个没有显示任何价值。我在夜间cron内进行此操作。 BASHGNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)

我的脚本告诉我ftp上传失败,因为FTP_PUT_RETVAL不包含值!

为什么会这样?我怎么能改变这个?我做错了什么?

    #!/bin/sh
    #
    # Filename: rh5-manager-cron.sh
    #
    # Purpose: Runs backup.cron, and FTP uploads backup to Linux4
    #
    # Usage: the program is run with no arguments. This program is
    # intended to run from manager cron, and redirection is handled inside the cron
    #     e.g. 00 1 * * * /u2/app/lbin/rh5-manager-cron.sh > /tmp/log/rh5-manager-cron.log 2>&1
    trap signalCaught ABRT EXIT HUP INT PIPE TERM QUIT
    signalCaught () {
        for file in $FTP_LOG_FILE $TMPF; do
            $BIN_HOME/rm_file $TMPF
        done
        exit
    }

    if [[ ! -r /u2/conf/ctrl/lettus.sh || ! -r /u2/app/lbin/fsh_sh_lib ]]; then
        printf "Cannot source environment.\n" >&2
        exit 1
    fi
    . /u2/conf/ctrl/lettus.sh
    . /u2/app/lbin/fsh_sh_lib

    #-------------------------------------------------------
    # Variables
    #-------------------------------------------------------
    PRG=${0##*/}
    FTPUSER=dummy
    FTPPASS=dummy
    FTPHOST=192.168.0.3
    BACKUPDIR=/backup
    FTPBACKUPNAME=Redhat5Backup.tgz
    FTPBACKUPFILE=$BACKUPDIR/$FTPBACKUPNAME
    LOGDIR=/tmp/log
    FTP_LOG_FILE=$LOGDIR/Redhat5FTP.log
    SENDLOGS=$C/sendlogs.dat
    ZOOT_XML=$C/zoot.xml
    TMPF=`mktemp` || exit 1

    #-------------------------------------------------------
    # Sanity
    #-------------------------------------------------------
    if ! isValidUser root manager; then
        printf "$PRG: Must be run as user 'root' or user 'manager'.\n" >&2
        exit 1
    fi

    if [[ ! -d $BACKUPDIR ]]; then
        logger "$PRG: $BACKUPDIR: Not a valid directory" >&2
        exit 1
    fi

    if [[ ! -d $LOGDIR ]]; then
        logger "$PRG: $LOGDIR: Not a valid directory" >&2
        exit 1
    fi

    if [[ ! -r $SENDLOGS || ! -r $ZOOT_XML ]]; then
        logger "$PRG: E-mail: Files are not readable: $SENDLOGS, $ZOOT_XML" >&2
        exit 1
    fi

    if ! which lftp >/dev/null 2>&1; then
        logger "$PRG: lftp: command not found" >&2
        exit 1
    fi

    # e-mail
    EMAIL_SUBJECT="Redhat5 FTP PUT"
    EMAIL_TO=$(email_to $SENDLOGS)
    EMAIL_FROM=$(email_from $ZOOT_XML)

    # ftp binary
    LFTP_BIN=$(which lftp 2>/dev/null)

    #-------------------------------------------------------
    # Functions
    #-------------------------------------------------------

    # calls lftp to upload a file to server non-interactively
    ftp_put() {
        $LFTP_BIN $LFTP_DEBUG -u ${FTPUSER},${FTPPASS} $FTPHOST <<-EOF
    put $FTPBACKUPFILE
    pwd
    ls $FTPBACKUPNAME
    quit
    EOF
    #^^^^^^^^^^^ leave the above indentation alone
    }

    main() {
        # Backup, and send manager logs
        logger "Running backup.cron..."
        echo
        backup.cron
        BACKUP_CRON_RETVAL=$?

        logger "Running fsh_sendlogs..."
        echo
        $SH_HOME/fsh_sendlogs 1

        # show ls listing
        logger "Here comes a directory listing..."
        echo
        /bin/ls -l /backup/Redhat5Backup.tgz
        echo

        # ftp upload
        logger "Running ftp upload..."
        echo
        ftp_put
        FTP_PUT_RETVAL=$?
        echo " -- debug: Line ${LINENO:-}: FTP_PUT_RETVAL=${FTP_PUT_RETVAL:-}"
    }

    checkSuccess() {
        if [[ "$BACKUP_CRON_RETVAL" -eq 0 ]]; then
            echo "Backup was successful."
            echo
            echo "*********************************"
            echo "   OK: Backup was successful."
            echo "*********************************"
            echo
        else
            echo "ERROR: Backup FAILED! "
            echo
            echo "*********************************"
            echo "     ERROR: Backup FAILED! "
            echo "*********************************"
            echo
        fi

        echo " -- debug: Line ${LINENO:-}: FTP_PUT_RETVAL=${FTP_PUT_RETVAL:-}"
        if [ "$FTP_PUT_RETVAL" -eq 0 ]; then
            echo "lftp: ftp file upload complete."
            echo
            echo "*********************************"
            echo "  OK: ftp file upload complete."
            echo "*********************************"
            echo
        else
            echo "lftp: error ftp file upload not successful."
            echo
            echo "*********************************"
            echo "      ERROR: file upload"
            echo "       NOT successful."
            echo "*********************************"
            echo
        fi
    }

    email_logs() {
        if [[ -z "$EMAIL_FROM" || -z $EMAIL_TO || -z $EMAIL_SUBJECT || ! -r $FTP_LOG_FILE ]]; then
            logger "$PRG: One of the variables is not correctly configured" >&2
            exit 1
        fi
        fsh_mail -r "${EMAIL_TO}" -F "${EMAIL_FROM}" -s "${EMAIL_SUBJECT}" -t "${FTP_LOG_FILE}"
        return
    }

    #----------------------------------------------------------------------
    # Main Program
    #----------------------------------------------------------------------
    main               | tee $FTP_LOG_FILE
    checkSuccess       | tee -a $FTP_LOG_FILE $TMPF
    cat $FTP_LOG_FILE >> $TMPF

    # E-mail ftp log file
    logger "Emailing ftp logfile"
    echo
    email_logs

    #eof

1 个答案:

答案 0 :(得分:3)

问题在于你正在使用:

main               | tee $FTP_LOG_FILE
checkSuccess       | tee -a $FTP_LOG_FILE $TMPF

由于管道,main中完成的工作是在子shell中完成的,而子shell不能在父shell中设置变量。因此,当checkSuccess(也在子shell中运行)查看结果时,它会看到父shell中的内容(无),而不是main中设置的内容。在子shell中运行。

如果放下管道,它就会开始工作。

更可靠,将checkSuccess的呼叫置于main功能中。或者使用这两种表示法中的一种或另一种:

{ main; checkSuccess; } | tee $FTP_LOG_FILE $TMPF
( main; checkSuccess )  | tee $FTP_LOG_FILE $TMPF

请注意,{ ... }表示法在第( ... )符号不需要的第二个函数后需要分号。但是,{ ... }机制中涉及的进程少了一个,而不是它会对整体性能产生任何可测量的差异(FTP时间占主导地位)。