在開發中,經常會遇到重刷以前腳本或提取以前數據,由於數據量極大,集羣資源不夠,只能按小時跑數據,怎樣編寫腳本輸入開始日期、開始小時、結束日期、結束小時自動跑數呢?
提供以下腳本供參考:
#!/bin/sh
#*****************************************************************************************
#*** 程序功能: 按天和小時循環導入分區數據
#*** 輸入參數: -s|--start-day <START_DAY> :需要導入的開始日期,格式YYYYMMDD
#*** -e|--end-day <END_DAY> :需要導入的結束日期,格式YYYYMMDD
#*** --start-hour <START_HOUR> :開始日期需要開始的小時,格式HH,可選參數,默認00
#*** --end-hour <END_HOUR> :結束日期需要結束的小時,格式HH,可選參數,默認23
#*** -f|--file <SOL_FILE> :SQL腳本絕對路徑名稱
#*** 編 寫 人: fuyun
#*** 編寫日期: 2020-01-22
#*** 修 改 人:
#*****************************************************************************************
umask 002
show_usage="[Usage] `date '+%F %T'` `basename $0` -s=YYYYMMDD -e=YYYYMMDD -f=filePath \n \
--start-day=YYYYMMDD --end-day=YYYYMMDD [--start-hour=HH] [--end-hour=HH] --file=filePath"
GETOPT_ARGS=`getopt -o s:e:f: -l start-day:,end-day:,start-hour::,end-hour::,file: -- "$@"`
# 將規範化後的命令行參數分配至位置參數($1,$2,...)
eval set -- "$GETOPT_ARGS"
# 開始小時默認爲00,結束小時默認爲23
#START_HOUR=00
#END_HOUR=23
# 獲取參數
while [ -n "$1" ]
do
case "$1" in
-s|--start-day) START_DAY=$2; shift 2;; #shift 2表示參數後移2個
-e|--end-day) END_DAY=$2; shift 2;;
--start-hour)
case "$2" in
"") START_HOUR=00; shift 2;;
*) START_HOUR=$2; shift 2;;
esac;;
--end-hour)
case "$2" in
"") END_HOUR=23; shift 2;;
*) END_HOUR=$2; shift 2;;
esac;;
-f|--file) SOL_FILE=$2; shift 2;;
--) break ;;
*) echo $1,$2,${show_usage}; break ;;
esac
done
# 可選參數,設置默認值,開始小時默認爲00,結束小時默認爲23
start-hour=${start-hour:00}
end-hour=${end-hour:23}
# check parameter
if [ -z "${START_DAY}" -o -z "${END_DAY}" -o -z "${START_HOUR}" -o -z "${END_HOUR}" -o -z "${SOL_FILE}" ]; then
echo -e "${show_usage} \n"
exit 1
fi
# 判斷小時參數是否爲00-23,開始日期不大於結束日期
#if [ ${START_HOUR} -ge 24 ] || [ ${START_HOUR} -lt 0 ] || [ ${END_HOUR} -ge 24 ] || [ ${END_HOUR} -lt 0 ] ]; then
# printf "[ERROR] `date '+%F %T'` --start-day:${START_DAY} greater than --end-day:${END_DAY}\n"
# exit 1
#fi
FLAG_DAY=${START_DAY}
LOG_FILE=$(echo "${SOL_FILE}" | awk -F"/" '{print $NF}' | awk -F"." '{print $1}')
LOG_PATH=/home/fuyun/logs/${LOG_FILE}
printf "[INFO] `date '+%F %T'` execute start day and hour is ${START_DAY} ${START_HOUR}\n"
printf "[INFO] `date '+%F %T'` execute end day and hour is ${END_DAY} ${END_HOUR}\n"
printf "[INFO] `date '+%F %T'` execute SQL file is ${SOL_FILE}\n"
printf "[INFO] `date '+%F %T'` looping execute.......\n"
executeHive() {
while :
do
local STAT_HOUR=00
local FLAG_HOUR=23
local START_DAY=$(date -d "$START_DAY 1day" +%Y%m%d)
local STAT_DAY=`date -d "${START_DAY} -1 day" +%Y%m%d`
# 判斷執行日期是否爲開始日期或結束日期
if [ ${STAT_DAY} -eq ${FLAG_DAY} ]; then
STAT_HOUR=${START_HOUR}
elif [ ${STAT_DAY} -eq ${END_DAY} ]; then
FLAG_HOUR=${END_HOUR}
fi
while :
do
local LOG_PATH=/home/fuyun/logs/${LOG_FILE}_${STAT_DAY}_${STAT_HOUR}.log
local SEVEN_DAY_BEFOR_LOG_PATH=/home/fuyun/logs/${LOG_FILE}_${SEVEN_DAY_BEFOR}*.log
printf "[INFO] `date '+%F %T'` log file name is ${LOG_PATH}\n"
printf "[INFO] `date '+%F %T'` current execute partition is dt=${STAT_DAY} hour=${STAT_HOUR}\n"
local startTime=`date '+%F %T'`
local startSeconds=$(date --date="${startTime}" +%s)
printf "[INFO] `date '+%F %T'` hivesql execute start time is ${startTime}\n"
# 執行hiveSQL腳本
hive --hiveconf DT=${STAT_DAY} --hiveconf HOUR=${STAT_HOUR} -f ${SOL_FILE}>>${LOG_PATH}.tmp 2>> ${LOG_PATH}
exitCode=$?
if [ $exitCode -ne 0 ];then
printf "[ERROR] `date '+%F %T'` hivesql execute ${SOL_FILE} is failed!!!\n"
exit $exitCode
else
local endTime=`date '+%F %T'`
local endSeconds=$(date --date="${endTime}" +%s)
printf "[INFO] `date '+%F %T'` hivesql execute end time is ${endTime}\n"
printf "[INFO] `date '+%F %T'` hivesql execute time is $(($((endSeconds-startSeconds))/60)) minutes\n"
printf "[INFO] `date '+%F %T'` hivesql ${STAT_DAY} data execute success!!!\n"
fi
# 因爲小時小於10時前面有0,shell腳本會認爲是八進制數字,所以要轉爲十進制數字
STAT_HOUR=$((10#$STAT_HOUR+1))
# 判斷小時是否小於10
if [ ${STAT_HOUR} -lt 10 ]; then
STAT_HOUR=0${STAT_HOUR}
fi
printf "[INFO] `date '+%F %T'` delete temp log ${LOG_PATH}.tmp\n"
rm ${LOG_PATH}.tmp
# 如果執行小時大於設置的結束小時,退出循環
if [ ${STAT_HOUR} -gt ${FLAG_HOUR} ]; then
break;
fi
done
find ${SEVEN_DAY_BEFOR_LOG_PATH} 2>/home/fuyun/logs/err.log.tmp
if [ $? -ne 0 ];then
printf "[WARN] `date '+%F %T'` ${SEVEN_DAY_BEFOR_LOG_PATH}: No such file or directory\n"
rm /home/fuyun/logs/err.log.tmp
else
printf "[INFO] `date '+%F %T'` delete log ${SEVEN_DAY_BEFOR_LOG_PATH}\n"
rm ${SEVEN_DAY_BEFOR_LOG_PATH}
fi
# 判斷執行日期是否等於結束日期,等於則退出循環
if [ ${STAT_DAY} -eq ${END_DAY} ]; then
break;
fi
done
}
if [ ${START_DAY} -gt ${END_DAY} ]; then
printf "[ERROR] `date '+%F %T'` --start-day:${START_DAY} greater than --end-day:${END_DAY}\n"
exit 1
elif [ ${START_HOUR} -ge 24 ] || [ ${START_HOUR} -lt 0 ] || [ ${END_HOUR} -ge 24 ] || [ ${END_HOUR} -lt 0 ]; then
printf "[ERROR] `date '+%F %T'` --start-hour:${START_DAY} or --end-hour:${END_DAY} is not 00-23 \n"
exit 1
else
executeHive
printf "[INFO] `date '+%F %T'` hivesql ${START_DAY}_${START_HOUR} to ${END_DAY}_${END_HOUR} data execute success!!!\n"
fi
從2020年1月22日的21點執行到2020年1月23日的22點,執行以下命令
sh excuteHourHiveSQLTest.sh --start-day 20200122 --end-day 20200123 --start-hour=21 --end-hour=22 --file SQL/temp_hour_test.sql
從2020年1月22日的00點執行到2020年1月23日的23點,執行以下命令
sh excuteHourHiveSQLTest.sh --start-day 20200122 --end-day 20200123 --file SQL/temp_hour_test.sql
或者以下命令
sh excuteHourHiveSQLTest.sh -s 20200122 -e 20200123 -f SQL/temp_hour_test.sql