5

アプリケーション サーバー環境にコードをデプロイしており、そのプロセスの一部として、サーバー上に多数の cron ジョブを作成しています。コードがプッシュされると、デプロイ スクリプトは、次を使用して必要な cron ジョブを問題なく作成します。

CRON_FILE=$SCRIPT_DIR/cron.txt 
if [[ ! -f "$CRON_FILE" ]]; then
        printf "Cron template file missing!\n\n"
        exit 1
fi
while read LINE || [[ -n "$LINE" ]]; do
        printf "\n> Adding cron job \"$LINE\"\n"
        crontab -l | { cat; echo "$LINE"; } | crontab -
done < $CRON_FILE

問題は、最初の展開の後、追加の展開によって重複した cron ジョブが作成されることです。

cron ジョブが既に存在するかどうかを検出する方法についての指針はありますか?

4

4 に答える 4

8

cron ジョブを追加するときは、一意のラベルの付いたコメントを含めてください。後でその一意のラベルを使用して、cron ジョブが存在するかどうかを判断したり、cron ジョブを「アンインストール」したりできます。

私はいつもこれをしています。これには再利用可能なスクリプトがあります。

#!/bin/sh
#
# Usage: 
# 1. Put this script somewhere in your project
# 2. Edit "$0".crontab file, it should look like this, 
#    but without the # in front of the lines
#0  *   *   *   *   stuff_you_want_to_do
#15 */5 *   *   *   stuff_you_want_to_do
#*  *   1,2 *   *   and_so_on
# 3. To install the crontab, simply run the script
# 4. To remove the crontab, run ./crontab.sh --remove
# 

cd $(dirname "$0")

test "$1" = --remove && mode=remove || mode=add

cron_unique_label="# $PWD"

crontab="$0".crontab
crontab_bak=$crontab.bak
test -f $crontab || cp $crontab.sample $crontab

crontab_exists() {
    crontab -l 2>/dev/null | grep -x "$cron_unique_label" >/dev/null 2>/dev/null
}

# if crontab is executable
if type crontab >/dev/null 2>/dev/null; then
    if test $mode = add; then
        if ! crontab_exists; then
            crontab -l > $crontab_bak
            echo 'Appending to crontab:'
            cat $crontab
            crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo; } | crontab -
        else
            echo 'Crontab entry already exists, skipping ...'
            echo
        fi
        echo "To remove previously added crontab entry, run: $0 --remove"
        echo
    elif test $mode = remove; then
        if crontab_exists; then
            echo Removing crontab entry ...
            crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^\$/ d" | crontab -
        else
            echo Crontab entry does not exist, nothing to do.
        fi
    fi
fi

スクリプトをcrontab.shプロジェクト ディレクトリに保存crontab.sh.crontabし、cron ジョブ定義を使用して を作成します。次に例を示します。

0 0 * * * echo hello world
0 0 * * * date
  • cron ジョブをインストールするには、単に実行します./crontab.sh
  • スクリプトは複数回実行しても安全です。一意のラベルが既に存在するかどうかを検出し、cron ジョブの追加を再度スキップします。
  • cron ジョブをアンインストールするには、次を実行します。./crontab.sh --remove

これも GitHub に置きます: https://github.com/janosgyerik/crontab-script

の説明sed -e "\?^$cron_unique_label\$?,/^\$/ d":

  • 最も単純な形式では、式は基本的に次のようになります。sed -e '/start/,/end/ d'
  • つまり、パターンを含む行を含め、開始パターンと終了パターンに一致する行の間のコンテンツを削除します
  • スクリプトは、シェル変数sedの値を展開する必要があるため、単一引用符ではなく二重引用符でコマンドを引用します。$cron_unique_label
  • 開始パターンは、パターンを囲む代わりに の\?^$cron_unique_label\$?ペアを使用します。?/$cron_unique_label/
  • 先頭?はバックスラッシュでエスケープする必要がありますが、正直なところ理由はわかりません。
  • は行頭と行末に^一致し、エスケープする必要があります。エスケープしないと、シェルはシェル変数の値を展開します。$$$?
  • 終了パターン/^\$/は比較的単純で、行頭とそれに続く行末、つまり空の行に一致し、ここ$でもエスケープする必要があります
  • d最後の はコマンドsedで、一致した行を削除し、 のコンテンツから効果的に削除しますcrontab -l。これにパイプすることができますcrontab -
于 2013-07-11T18:26:19.770 に答える
1

あなたのスクリプト janos はすばらしく、完璧に動作し、まさに私が探していたものでした。複数の xxx.crontab テンプレートを管理できませんでした。あなたのスクリプトは正常に動作し、少し修正してブートストラップ ルーチンに追加したので、xx.crontab ファイル名の最初のパラメーター $1 を渡し、2 番目のパラメーター $2 を削除することができます。親シェルスクリプトがあり、条件付きで追加/削除するcrontabファイルのすべてまたは組み合わせを決定します。

ここに私の変更を含むスクリプトが含まれています:

#!/bin/sh
#
# Usage:
# 1. Put this script somewhere in your project
# 2. Edit "$1".crontab file, it should look like this,
#    but without the # in front of the lines
#0  *   *   *   *   stuff_you_want_to_do
#15 */5 *   *   *   stuff_you_want_to_do
#*  *   1,2 *   *   and_so_on
# 3. To install the crontab, run ./crontab.sh <nameOfCronTabfile>
# 4. To remove the crontab, run ./crontab.sh <nameOfCronTabfile> --remove

cd $(dirname "$0")

test "$2" = --remove && mode=remove || mode=add

cron_unique_label="# cmID:$PWD|$1#"

crontab="$1".crontab
crontab_bak=$crontab.bak
test -f $crontab || cp $crontab.sample $crontab

crontab_exists() {
    crontab -l 2>/dev/null | grep -x "$cron_unique_label" >/dev/null 2>/dev/null
}

# if crontab is executable
if type crontab >/dev/null 2>/dev/null; then
    if test $mode = add; then
        if ! crontab_exists; then
            crontab -l > $crontab_bak
            echo 'Appending to crontab:'
            echo '-----------------------------------------------'
            cat $crontab
            crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo "# cm #"; } | crontab -
        else
            echo 'Crontab entry already exists, skipping ...'
            echo
        fi
        echo '-----------------------------------------------'
        echo "To remove previously added crontab entry, run: $0 $1 --remove"
        echo
    elif test $mode = remove; then
        if crontab_exists; then
            echo 'Removing crontab entry ...'
            crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^# cm #\$/ d" | crontab -
        else
            echo 'Crontab entry does not exist, nothing to do.'
        fi
    fi
fi

更新: 申し訳ありませんが、crontab を削除するための弱い空の行パターンに気づきませんでした。手動で追加された crontab を含め、見つかった crontab id の後のすべてを単純に削除します。空行終了パターンを小さな終了タグに変更。したがって、次のようにcrontabを追加します。

crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo "# cm #"; } | crontab -

..そして、このcronのみを正確に削除します:

crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^# cm #\$/ d" | crontab -
于 2014-06-26T23:26:25.210 に答える
0

コードで行うこともできます: まず bash で、マニュアルを確認してください: man 2 open:

int fd = open('/tmp/1.txt', O_CREAT|O_EXCL)
if (fd === -1) {
   print "job exist"
   exit(1)
}
//unlink()
// your code

JS バージョン:

const fs = require('fs')
try {
const fd = fs.openSync('/tmp/1.txt', 'wx')
} catch(err) {
  console.log('job exist')
  process.exit(0)
}

fs.unlinkSync('/tmp/1.txt')
fs.appendFileSync(fd, 'pid', 'utf8');
于 2020-01-16T21:48:46.493 に答える