私はここでこの記事を読み、チェッカーを自分で少し取り上げて、自分自身と他の人のために楽しいことをしようと決めました。
私のスクリプトは何の役にも立ちませんが、多かれ少なかれbashの作家にとっては何かを教えてくれると思います。コメントがあれば、私の間違いを指摘した人々から学びます。
入門
スクリプトは、デーモンによってバックグラウンドで実行されます。 すぐにプロセス自体が常に記憶に残ることに同意する必要があると思うので、「親」と呼びます。 親は特定のディレクトリで特定のファイルを検索し、存在する場合はファイルが削除されてプロセスが開始されます。これを「子孫」と呼びます。その目的はしばらくスリープし、完了します。 ただし、親は単位時間あたり複数の子孫を実行する必要はありません。 原則として、上記の記事を読んだ場合、その意味は明確だと思います。
で始まる
そこで、変数を定義します
# FILE_NAME="run_Lola_run" # WATCH_DIR="/home/mcleod/test" # LOCK_FILE="${WATCH_DIR}/monitor_file.lock" # PID_FILE="${WATCH_DIR}/monitor_file.pid" # JOB_LOCK_FILE="${WATCH_DIR}/job_monitor_file.lock" # LOG="${WATCH_DIR}/monitor_file_work.log" # ERR_LOG="${WATCH_DIR}/monitor_file_error.log" # RANGE=100
次に、親の開始と停止を便利に制御するために、小さな条件を記述します
case $1 in "start") start ;; "stop") stop ;; *) usage ;; esac exit
フレームワークの準備が整い、すべての変数も定義されました。使用する関数を説明する必要があります
- start-スクリプトをデーモンモードにする開始関数
- stop-デーモン停止機能
- 使用方法-ヘルプ画面出力機能
- _log-ログファイルに書き込む関数
- run_job-子孫起動関数
ここで、関数がより複雑になるにつれて、関数を説明します。 それらの中で最も単純なのは、使用関数です。次のようになります。
# usage() { echo "$0 (start|stop)" }
複雑さの次は_log関数です
# _log() { process=$1 shift echo "${process}[$$]: $*" }
デーモン停止機能
# stop() { # pid , pid if [ -e ${PID_FILE} ] then _pid=$(cat ${PID_FILE}) kill $_pid rt=$? if [ "$rt" == "0" ] then echo "Daemon stop" else echo "Error stop daemon" fi else echo "Daemon is't running" fi }
ここでは、ロギング機能を使用しません。 ここで、メッセージはコンソールに表示されるはずです。
ここで、おそらく最も複雑な開始機能を提供します。 作業のすべてのロジックと、スクリプトの悪魔化の瞬間が含まれています。
# start() { # pid if [ -e $PID_FILE ] then _pid=$(cat ${PID_FILE}) if [ -e /proc/${_pid} ] then echo "Daemon already running with pid = $_pid" exit 0 fi fi # touch ${LOG} touch ${ERR_LOG} # , cd / # , exec > $LOG exec 2> $ERR_LOG exec < /dev/null # , . ( # trap "{ rm -f ${PID_FILE}; exit 255; }" TERM INT EXIT # while [ 1 ] do # if ls -1 ${WATCH_DIR} | grep "^${FILE_NAME}$" 2>&1 >/dev/null then _log "parent" "File found" rm -f ${WATCH_DIR}/${FILE_NAME} _log "parent" "File deleted" # number=$RANDOM let "number %= $RANGE" _log "parent" "Genereated number $number" JOBS[${#JOBS[@]}]=$number fi # 0, , if [ "${#JOBS[@]}" -gt "0" ] then if [ ! -e ${JOB_LOCK_FILE} ] then run_job _log "parent" "Running job with pid $!" unset JOBS[0] JOBS=("${JOBS[@]}") _log "parent" "Jobs in queue [${#JOBS[@]}]" fi fi # sleep 1 done exit 0 )& # pid , echo $! > ${PID_FILE} }
さて、子孫起動機能自体
# . JOBS, run_job() { # . /, .. ( # trap "{ rm -f ${JOB_LOCK_FILE}; exit 255; }" TERM INT EXIT # if [ ! -e ${JOB_LOCK_FILE} ] then # pid , echo "$$" > ${JOB_LOCK_FILE} _log "child" "Job with pid $$" # seconds=${JOBS[0]} # , , unset JOBS _log "child" "Sleep seconds $seconds" sleep ${seconds} else _log "child" "Lock file is exists" fi # exit 0 )& }
さて、今あなたが上記のすべてをファイルに結合して実行する権利を与えれば、あなたにとって難しいことではないと思います。 ところで、開始する前に、WATCH_DIR変数の値を、スクリプトがrun_Lola_runというファイルを検索するディレクトリへのパスに変更することをお勧めします。
ここに私の出力ログファイルがあります
parent[32338]: File found parent[32338]: File deleted parent[32338]: Genereated number 96 parent[32338]: Running job with pid 32385 parent[32338]: Jobs in queue [0] child[32338]: Job with pid 32338 child[32338]: Sleep seconds 96 parent[32338]: File found parent[32338]: File deleted parent[32338]: Genereated number 46 parent[32338]: File found parent[32338]: File deleted parent[32338]: Genereated number 1 parent[32338]: Running job with pid 32694 parent[32338]: Jobs in queue [1] child[32338]: Job with pid 32338 child[32338]: Sleep seconds 46 parent[32338]: Running job with pid 371 parent[32338]: Jobs in queue [0] child[32338]: Job with pid 32338 child[32338]: Sleep seconds 1
この投稿がbashの開発に役立つことを願っています。
PS:注意深い読者は、同じプロセス番号がログのどこにでもあることを見たに違いありません。 なぜなら bashには純粋なフォークはありません。ここでは、必要なコードを()&で実行することでエミュレーションが発生します。 そして、bashの現在のプロセス番号が$$変数に格納されていることがわかります。 したがって、同じプロセス番号がログファイルに表示されます。 これが、start関数がecho $!という行で終わる理由です。 > $ {PID_FILE}。