簡易ジョブネット - ジョブスケジューラで提供されるようなジョブの実行制御をシェルで行う

・但し、あくまでも環境整備が間に合わない時、できない時のみ使用。  (本番環境と同じ環境が開発環境に用意できるなら、そっちの方がいいに決まってる。。)

◆実行を行うジョブネット
jobnet.gif

◆処理構成
jobnet_system.gif

◆ジョブネット定義ファイル(test_jobnet)
(フローに合わせて定義ファイルを編集)

#!/bin/bash

# 各ジョブの起動にコンソールに表示(0:表示しない 1:表示する)
DISP_FLG=0

# 実行結果の表示(0:表示しない 1:表示する)
DISP_RESULT=1

# ログ出力先(ブランク時はログファイルを作成しない)
LOG_DIR=/tmp/log

# ジョブネット名
JOBNET_NAME=TEST_JOBNET

# シェルファイルPATH
JOB_PATH[1]=./job01.sh
JOB_PATH[2]=./job02.sh
JOB_PATH[3]=./job03.sh
JOB_PATH[4]=./job04.sh
JOB_PATH[5]=./job05.sh
JOB_PATH[6]=./job06.sh

# 各ジョブの先行ジョブ ※JOB_PATHのIDを指定。※複数の時はカンマ区切り
PRE_JOB[1]=
PRE_JOB[2]=1
PRE_JOB[3]=1
PRE_JOB[4]=1
PRE_JOB[5]=2,3,4
PRE_JOB[6]=5

◆ジョブネット実行用シェル(my_jobnet.sh)
(編集の必要なし)

#!/bin/bash
###########################################
# 処理概要 : 簡易ジョブネット
# 作成日   : 2007-11-01
# 作成者   : D.Magata
###########################################

# ジョブ起動ファイル名をセット
JOB_SH=$0

## ジョブネット開始
start_jobnet(){

	# 引数チェック
	if [ "${1}" == "" ]; then
		echo " "
		echo "[実行エラー] ジョブネット定義ファイルを指定して下さい"
		disp_help
		exit 1
	else
		# ジョブネット定義ファイルの存在確認
		if ! test -r ${1} ; then
			echo " "
			echo "[実行エラー] ジョブネット定義ファイル(${1})がありません"
			disp_help
			exit 1
		fi
	fi

	# 結果格納用ディレクトリを作成
	DATE_STR=`date +%Y%m%d%H%M%S`
	TMP_PATH=`pwd`"/tmp"${DATE_STR}"/"
	if ! test -d $TMP_PATH ; then
		mkdir $TMP_PATH
	fi

	# ジョブネット定義ファイルを読込
	export ENV_FILE=${TMP_PATH}jobnet_env
	cp $1 $ENV_FILE
	echo TMP_PATH=${TMP_PATH} >> ${ENV_FILE}
	echo TMP_LOG_FILE=${TMP_PATH}jobnet.log >> ${ENV_FILE}
	. ${ENV_FILE}

	# ログファイル名をセット
	LOG_FILE=""
	if [ "${LOG_DIR}" != "" ] ; then
		LOG_FILE="${LOG_DIR}${JOBNET_NAME}_${DATE_STR}.log"
	fi
	echo LOG_FILE=${LOG_FILE} >> ${ENV_FILE}

	# ジョブ数を取得
	i=1
	while [ "${JOB_PATH[$i]}" != "" ]
	do
		i=`expr $i + 1`
	done
	export JOB_CNT=`expr $i - 1`
	echo JOB_CNT=${JOB_CNT} >> ${ENV_FILE}

	# 先頭ジョブを起動する
	for i in `seq 1 ${JOB_CNT}`
	do
		PRE_LIST=${PRE_JOB[$i]}
		if [ "${PRE_LIST}" == "" ]; then
			${JOB_SH} job ${i} &
		fi
	done

	exit 0
}

## ジョブ開始
start_job(){

	# 環境変数ファイルを読込
	. ${ENV_FILE}

	# 実行対象ジョブのID,PATHをセット
	if [ "$1" != "" ]; then
		JOB_ID=$1
		JOB_RES_FILE=${TMP_PATH}$1
		JOB_FILE=${JOB_PATH[$JOB_ID]}
		shift
	fi

	# 既に実行済みの場合は終了
	if test -r ${JOB_RES_FILE} ; then
		exit 0
	fi

	# 先行ジョブを取得
	ARG_CNT=0
	while [ "$1" != "" ] ; do
		ARG_CNT=`expr ${ARG_CNT} + 1`
		STATUS_FILE[${ARG_CNT}]=${TMP_PATH}$1
		shift 1
	done

	# 全ての先行ジョブが終了していなければ終了
	for i in `seq 1 ${ARG_CNT}`;
	do
		if ! test -r ${STATUS_FILE[$i]} ; then
			exit 0
		fi
	done

	# 先行ジョブの実行結果を取得
	ABEND_FLG="0"
	WAIT_FLG="0"
	for i in `seq 1 ${ARG_CNT}`;
	do
	PRE_RESULT=`cat ${STATUS_FILE[$i]}`
		if [ "${PRE_RESULT}" == "" ]; then
			WAIT_FLG="1"
		fi
		if [ "${PRE_RESULT}" != "0" ]; then
			ABEND_FLG="1"
		fi
	done

	# 先行ジョブが実行中の時は終了
	if [ "${WAIT_FLG}" == "1" ]; then
		exit 0
	fi

	# 既に実行済みの場合は終了
	if test -r ${JOB_RES_FILE} ; then
		exit 0
	else
		touch ${JOB_RES_FILE}
	fi

	# 先行ジョブの実行結果によって、ジョブ実行/非実行
	if [ ${ABEND_FLG} == "0" ]; then

		if [ ${DISP_FLG} == "1" ]; then
			echo "${JOB_FILE}を起動"
		fi

		echo "["${JOB_ID}"] ${JOB_FILE} 開始 "`date +%Y`-`date +%m`-`date +%d` `date +%H`:`date +%M`:`date +%S` >> ${TMP_LOG_FILE}

		# シェルを実行
		$JOB_FILE

		echo "["${JOB_ID}"] ${JOB_FILE} 終了 "`date +%Y`-`date +%m`-`date +%d` `date +%H`:`date +%M`:`date +%S` >> ${TMP_LOG_FILE}

		JOB_RESULT=$?
		if [ ${JOB_RESULT} != "0" ]; then
			JOB_RESULT=1
		fi
	else
		JOB_RESULT="-1"
	fi

	# 実行結果をファイルに出力
	echo ${JOB_RESULT} > ${JOB_RES_FILE}

	# 後続ジョブを実行
	for i in `seq 1 ${JOB_CNT}`;
	do
		JOBLIST="${PRE_JOB[$i]},"
		if [ "${JOBLIST}" != "" ]; then
			while [ ${JOBLIST} ]
			do
				CUR_JOB=${JOBLIST%%,*}
				JOBLIST=${JOBLIST#*,}
				if [ "${CUR_JOB}" == "${JOB_ID}" ]; then
					PRE_JOBLIST="${PRE_JOB[$i]},"
					j=0
					while [ ${PRE_JOBLIST} ]
					do
						PRE_JOB_ARRAY[${j}]=${PRE_JOBLIST%%,*}
						PRE_JOBLIST=${PRE_JOBLIST#*,}
						j=`expr ${j} + 1`
					done
					$JOB_SH job ${i} ${PRE_JOB_ARRAY[@]} &
					break;
				fi
			done
		fi
	done

	# 実行結果の表示(全ジョブ終了時)
	if [ "${DISP_RESULT}" == "1" ]; then
		disp_result
	fi

	# ログファイルをコピー
	if [ "${LOG_FILE}" != "" ]; then
		cp ${TMP_LOG_FILE} ${LOG_FILE}
	fi

	# 一時ディレクトリを削除
	rm -rf ${TMP_PATH}

	exit 0
}


## 実行結果の表示
disp_result(){

	# 最終ジョブ判定
	for i in `seq 1 ${JOB_CNT}`
	do
		if ! test -r ${TMP_PATH}${i} ; then
			exit 0
		else
			JOB_STATUS=`cat ${TMP_PATH}${i}`
			if [ "$JOB_STATUS" == "" ]; then
				exit 0
			fi
		fi
	done

	# 最終ジョブの時は結果表示
	echo " "
	echo "===== ジョブネット実行結果(${JOBNET_NAME}) ====="
	for i in `seq 1 ${JOB_CNT}`
	do
		JOB_STATUS=`cat ${TMP_PATH}${i}`
		if [ "${JOB_STATUS}" == "0" ]; then
			echo "[""${i}""] ${JOB_PATH[$i]} 正常終了"
		fi
		if [ "${JOB_STATUS}" == "1" ]; then
			echo "[""${i}""] ${JOB_PATH[$i]} 異常終了"
		fi
		if [ "${JOB_STATUS}" == "-1" ] ; then
			echo "[""${i}""] ${JOB_PATH[$i]} 未実行"
		fi
	done
	echo "----- 実行ログ ---------------------------------"
	cat ${TMP_LOG_FILE}
	echo "================================================"
}


## HELPの表示
disp_help(){
	echo " "
	echo "	実行例)"
	echo " "
	echo "	${0} ./ジョブネット定義ファイル"
	echo " "
	echo "	 または "
	echo " "
	echo "	${0} /home/xxxx/xxxxx/ジョブネット定義ファイル"
	echo " "
}


# 処理を実行
case $1 in
job)
	shift
	start_job $*
	;;
*)
	start_jobnet $*
	exit 0
esac


◆実行例

# ./my_jobnet.sh ./test_jobnet
#
===== ジョブネット実行結果(TEST_JOBNET) =====
[1] ./job01.sh 正常終了
[2] ./job02.sh 正常終了
[3] ./job03.sh 正常終了
[4] ./job04.sh 正常終了
[5] ./job05.sh 正常終了
[6] ./job06.sh 正常終了
----- 実行ログ ---------------------------------
[1] ./job01.sh 開始 2007-11-15 13:15:55
[1] ./job01.sh 終了 2007-11-15 13:15:59
[3] ./job03.sh 開始 2007-11-15 13:15:59
[2] ./job02.sh 開始 2007-11-15 13:15:59
[4] ./job04.sh 開始 2007-11-15 13:15:59
[3] ./job03.sh 終了 2007-11-15 13:16:02
[2] ./job02.sh 終了 2007-11-15 13:16:02
[4] ./job04.sh 終了 2007-11-15 13:16:09
[5] ./job05.sh 開始 2007-11-15 13:16:09
[5] ./job05.sh 終了 2007-11-15 13:16:12
[6] ./job06.sh 開始 2007-11-15 13:16:12
[6] ./job06.sh 終了 2007-11-15 13:16:15
================================================

添付ファイル: filejobnet_system.gif 300件 [詳細] filejobnet.gif 286件 [詳細]

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-06-11 (木) 00:48:54 (5425d)