【发布时间】:2015-06-26 10:36:29
【问题描述】:
解决方案:
见Send stderr/stdout messages to function and trap exit signal
编辑 我发现我在原始帖子中不够精确,对此感到抱歉!因此,现在我将包含我的 bash 脚本的代码示例,其中包含一些精致的问题:
我的四个问题:
- 如何在 STEP 中的 mysql 命令中发送 stdout 到 file 和 stderr 到 log() 函数2
- 如何将 stdout 和 stderr 发送到 gzip STEP 2 和 rsync 命令 STEP 3 中的 log() 函数?
- 如何读取上述问题1和问题2中log()函数中的stdout和stderr?
- 如何在 onexit() 函数中仍然捕获所有错误?
通用:我希望 stdout 和 stderr 转到 log() 函数,以便可以根据特定格式将消息放入特定日志文件,但在某些情况下,例如 mysqldump 命令,标准输出需要去文件。另外,发生错误并发送到 stderr,我想在 log 语句完成后结束 onexit() 函数。
#!/bin/bash -Eu
# -E: ERR trap is inherited by shell functions.
# -u: Treat unset variables as an error when substituting.
# Example script for handling bash errors. Exit on error. Trap exit.
# This script is supposed to run in a subshell.
# See also: http://fvue.nl/wiki/Bash:_Error_handling
# Trap non-normal exit signals: 2/INT, 3/QUIT, 15/TERM,
trap onexit 1 2 3 15 ERR
# ****** VARIABLES STARTS HERE ***********
BACKUP_ROOT_DIR=/var/app/backup
BACKUP_DIR_DATE=${BACKUP_ROOT_DIR}/`date "+%Y-%m-%d"`
EMAIL_FROM="foo@bar.com"
EMAIL_RECIPIENTS="bar@foo.com"
...
# ****** VARIABLES STARTS HERE ***********
# ****** FUNCTIONS STARTS HERE ***********
# Function that checks if all folders exists and create new ones as required
function checkFolders()
{
if [ ! -d "${BACKUP_ROOT_DIR}" ] ; then
log "ERROR" "Backup directory doesn't exist"
exit
else
log "INFO" "All folders exists"
fi
if [ ! -d "${BACKUP_DIR_DATE}" ] ; then
mkdir ${BACKUP_DIR_DATE} -v
log "INFO" "Created new backup directory"
else
log "WARN" "Backup directory already exists"
fi
}
# Function executed when exiting the script, either because of an error or successfully run
function onexit() {
local exit_status=${1:-$?}
# Send email notification with the status
echo "Backup finished at `date` with status ${exit_status_text} | mail -s "${exit_status_text} - backup" -S from="${EMAIL_FROM}" ${EMAIL_RECIPIENTS}"
log "INFO" "Email notification sent with execution status ${exit_status_text}"
# Print script duration to the console
ELAPSED_TIME=$((${SECONDS} - ${START_TIME}))
log "INFO" "Backup finished" "startDate=\"${START_DATE}\", endDate=\"`date`\", duration=\"$((${ELAPSED_TIME}/60)) min $((${ELAPSED_TIME}%60)) sec\""
exit ${exit_status}
}
# Logs to custom log file according to preferred log format for Splunk
# Input:
# 1. severity (INFO,WARN,DEBUG,ERROR)
# 2. the message
# 3. additional fields
#
function log() {
local print_msg="`date +"%FT%T.%N%Z"` severity=\"${1}\",message=\"${2}\",transactionID=\"${TRANS_ID}\",source=\"${SCRIPT_NAME}\",environment=\"${ENV}\",application=\"${APP}\""
# check if additional fields set in the 3. parameter
if [ $# -eq 3 ] ; then
print_msg="${print_msg}, ${3}"
fi
echo ${print_msg} >> ${LOG_FILE}
}
# ****** FUNCTIONS ENDS HERE ***********
# ****** SCRIPT STARTS HERE ***********
log "INFO" "Backup of ${APP} in ${ENV} starting"
# STEP 1 - validate
log "INFO" "1/3 Checking folder paths"
checkFolders
# STEP 2 - mysql dump
log "INFO" "2/3 Dumping ${APP} database"
mysqldump --single-transaction ${DB_NAME} > ${BACKUP_DIR_DATE}/${SQL_BACKUP_FILE}
gzip -f ${BACKUP_DIR_DATE}/${SQL_BACKUP_FILE}
log "INFO" "Mysql dump finished."
# STEP 3 - transfer
# Files are only transferred if all commands has been running successfully. Transfer is done with use of rsync
log "INFO" "3/3 Transferring backup file"
rsync -r -av ${BACKUP_ROOT_DIR}/ ${BACKUP_TRANSFER_USER}@${BACKUP_TRANSFER_DEST}
# ****** SCRIPT ENDS HERE ***********
onexit
谢谢!
【问题讨论】: