質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • Linux

    4521questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • Git

    1677questions

    Gitはオープンソースの分散バージョン管理システム(DVCS)です。

GitHubからLinuxサーバーにPULLするバッチ処理について

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 862

hyskyo

score 68

問題:GitHubからLinuxサーバーにあるディレクトリーに自動的にリアルタイムでPullできるようにはなっていますがいくつかのディレクトリーに同時にPULLした時にプロセスの処理が次々と実行されてサーバーが落ちしまいます。

質問・実行したいこと:
どうしたい上記の問題を解決できますか?
これを先のプロセスが終わってから次の処理が実行できるように変更したいのですが良くわからなくて誰かが教えていただきますか?

こちらのGitバッチ処理です.

#!/bin/bash
#指定されたブランチをpullする
export PATH=$PATH:/usr/local/bin

GIT_DIR=.git

# pull対象ブランチ
BRANCH_ARR=("master" "master")

# 更新対象ディレクトリ
DIR=/var/www/vhosts/system
DIR_ARR=("bokemon" "lalago")

# log
LOG=/var/www/vhosts/system/logs/git/gitpull.log

datestr=`date +%Y/%m/%d_%H:%M:%S`
echo "$datestr git pull start." 1>>$LOG 2>&1

for (( i=0; i<${#DIR_ARR[@]}; i++ ))
do
        target_dir=${DIR_ARR[$i]}
        branch=${BRANCH_ARR[$i]}

        # 反映先ディレクトリへ移動する
        cd "${DIR}/${target_dir}"
        echo "${DIR}/${target_dir}" 1>>$LOG 2>&1

        # 反映したいブランチと現在のブランチが同じか確認する
        current=`git rev-parse --abbrev-ref HEAD`
        if [ "$current" != "$branch" ]; then
            # $BRANCHと異なる場合はcheckoutし直す
            `git checkout $BRANCH` 1>>$LOG 2>&1
        fi

        # git fetch後、diffで差分があるか確認する
        fetch=`git fetch`
        diff=`git diff origin/$branch`

        # 更新処理を実施
        if [ ${#diff} != 0 ] ; then
            # 差分がある場合は反映する
            `git reset --hard origin/$branch` 1>>$LOG 2>&1
            echo "git reset --hard origin/${branch}"

        fi
done

# バッチ終了
datestr=`date +%Y/%m/%d_%H:%M:%S`
echo "$datestr git pull finish." 1>>$LOG 2>&1

exit 0
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2016/08/31 20:57

    シングルクオートではなくバッククォートでやるか、コード部分を選択後に<code> をクリックね

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2016/08/31 20:58

    修正とすれ違った

    キャンセル

回答 3

0

このGitバッチ処理がどうやって起動されているのか分かりませんが…

(1) 更新対象リスト(ファイル)を最新にメンテナンスする
(2) 上記リストから1件分を更新して、リストから消し込む

という処理をつくって cron から一定時間間隔で起動する
というのはどうでしょうか。
--- 追記 ---

//思いつきなので、細かいとこは自分でつめてくださいね。

# 更新処理を実施
        if [ ${#diff} != 0 ] ; then
            # 差分がある場合は反映する
            #`git reset --hard origin/$branch` 1>>$LOG 2>&1
            echo "git reset --hard origin/${branch}" >>hoge.txt

        fi


という感じで、まずは実行せずにリストの更新だけ実施。
それとは別のスクリプトで

exe=`head -1 hoge.txt`
sed -e '1d' hoge.txt >tmp.txt
$exe
mv tmp.txt hoge.txt


という感じで実行。
hoge.txtの更新に矛盾がおきないように調査と実行の
タイミングを調整する必要があります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/31 21:19

    ご指摘ありがとうございます。

    一定時間間隔で処理する今よりは持ち時間長くはなりますが処理プロセスがたくさんたまって落ちたことがあります、なので何がいい方法あるかと思って質問させていただきました。

    1, 2についてですが良く理解できませんでした、すみません少しわかりやすく説明していただきませんか?

    /etc/cron.d/gitpull にて # 月曜(1)〜日曜(7) 6時〜24時で設定しています。

    キャンセル

  • 2016/09/01 16:15

    ありがとうございます!!
    試させていただきます。

    キャンセル

0

この手の処理だったらうちの場合

  1. lock ファイルの有無を確認し存在しかつn分以内の場合処理を中断する。
  2. work ディレクトリに git pull を実効する。
  3. work ディレクトリと prod ディレクトリを rsync で反映する 。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/01 16:15

    ありがとうございます!!
    試させていただきます。

    キャンセル

0

これを先のプロセスが終わってから次の処理が実行できるように変更したいのですが良くわからなくて誰かが教えていただきますか?

ロックで排他制御して、1個ずつしか処理しないようにする技法ということであれば、 flock コマンドで実装するのが良いかと思います。 flock コマンドで実装する場合の lock, unlock 関数の例を示します。

GIT_LOCK_FILE=/var/run/git.lock
GIT_LOCK_TIMEOUT=600

# prepare FD for lock.
if ! exec {lockFd}>> $GIT_LOCK_FILE; then
    echo "$datestr fail to open lock file($GIT_LOCK_FILE)." 1>>$LOG 2>&1
    exit 1
fi

lock() {
    if ! flock-w $GIT_LOCK_TIMEOUT $lockFd >/dev/null 2>&1; then
        echo "$datestr fail to aquire lock, another git pull process may be running." 1>>$LOG 2>&1
        return 1
    fi
    return 0
}

unlock() {
    flock -u $lockFd
}

flockコマンドでのロックの実装は、シェルスクリプトで旧来から常套手段とされているロックファイルの存在だけを確かめる方法と比べると、以下のメリットが有ります。

  • タイムアウト処理を実装してくれる(上記のコードで 10 分待ってロックが取れなければ諦めます)
  • ロックを保持しているプロセスが unlock を実行せずに異常終了してもロックが開放される

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/01 16:14

    ありがとうございます!!
    試させていただきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Linux

    4521questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • Git

    1677questions

    Gitはオープンソースの分散バージョン管理システム(DVCS)です。