私は展開スクリプトを持っています。ユーザーcrontab
に何かを追加する必要があります(XXX日ごとにログをクリーンアップするスクリプトをトリガーします)。ただし、これは最初の展開時または更新が必要なときにのみ実行する必要があります。
(xxx.py deploy env
またはxxx.py update env
を実行できます)
だから私はこれをしなければなりません:
Check if my cronJob already exist
Put my cronJob if it does not already exist
or
update my cronjob if one of the parameter of the command is different
crontab -e
を使用したり、crontab
ファイルを編集したりせずにcrontab
に何かを追加/チェック/削除する方法がわかりません(ダウンロード、再書き込み、再アップロード)
PS:これはユーザー固有のcronjobであり、「webadmin」が実行する予定であり、Sudoを使用して実行するべきではありません。
コンテンツがそこにあるべきものと一致するかどうかを最初にチェックし、一致しない場合にのみ更新するには:
if [[ $(crontab -l | egrep -v "^(#|$)" | grep -q 'some_command'; echo $?) == 1 ]]
then
echo $(crontab -l ; echo '* 1 * * * some_command') | crontab -
fi
しかし、これはそのcronタスクの周りに別のスクリプトを構築するのに十分複雑になります。
stdinを介して文字列をcrontabに送信できます(これにより、以前のcrontabエントリがすべて消去されます)。
echo "* 1 * * * some_command" | crontab -
これはsshでも正しく機能するはずです。
echo "* 1 * * * some_command" | ssh user@Host "crontab -"
ファイルに追加したい場合は、これを使用できます:
# on the machine itself
echo "$(echo '* 1 * * * some_command' ; crontab -l)" | crontab -
# via ssh
echo "$(echo '* 1 * * * some_command' ; ssh user@Host crontab -l)" | ssh user@Host "crontab -"
記録として、/etc/cron.d/
の使用をお勧めします。ここではrootだけがファイルを書き込むことができますが、エントリは任意のユーザーとして実行できます(Sudo
は必要ありません)。
echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' > ~/webadmin.cron
scp -p ~/webadmin.cron root@remote_Host:/etc/cron.d/webadmin
これは複数回適用でき、コピーする前に必要に応じてローカルwebadmin.cron
ファイルを更新します。
プロビジョニングを削除することもできます。
ssh -q root@remote_Host rm -f /etc/cron.d/webadmin
多くの場合、scp
/ssh
コマンドにrootのパスワードを提供できないことに注意してください。代わりに、公開鍵/秘密鍵証明書を設定する必要があります。また、暗黙的にローカルアカウント(それが何であれ)は、リモートサーバーへの完全なrootアクセス権を持ちます。それがあなたの特定のシナリオのショーストッパーになるかどうかは現時点では不明です。
自分でロールするのではなく、Ansible *を使用することを強くお勧めします。またはPuppetまたはChef —しかし、Ansibleは、このようなインフラストラクチャなしのデプロイスクリプトに適しています。
これは、このような問題を解決するためのモジュールがすでにあり、構成管理ツールに基本的な設計目標として idempotence があるためです。これは、誤って(または意図的に)必要な場合にのみ変更できるという特性です)もう一度実行します。
特に、Ansibleの cronモジュール は、ユーザーのcrontabを変更できます。おまけとして、後でシステムのcrontabを使用するように調整する場合は、書き換えではなく非常に簡単なTweakになります。
*免責事項:私はRed Hatで働いており、AnsibleはRed Hatがスポンサーとなっているプロジェクトです。
ターゲットアカウントを介してcronジョブを追加する場合は、crontab -e
を実行します。このコマンドは、エディターを介してcrontabを渡します。必要に応じてcrontabを変更するエディターコマンドを使用するように指示します。エディターコマンドは、一時ファイルの名前が追加されたシェルスニペットとして実行されます。
unset VISUAL
EDITOR='update_crontab () {
set -e
new=$(mktemp)
if <"$1" grep -v "^#" | grep -w do_stuff; then
# Remove existing entries containing do_stuff
grep -v -w do_stuff "$1" >"$new"
else
cp "$1" "$new"
fi
# Add the new entry
echo "1 2 3 4 5 do_stuff --new-options" >>"$new"
mv "$new" "$1"
}
update_crontab' crontab -e
この方法は、ネイティブのcrontab -l | … | crontab -
よりも信頼性が高いです。crontabが同時に編集されると、競合状態に対して脆弱になるため、crontab -l
の呼び出しとcrontab -
の呼び出しの間に行われた変更が元に戻されます。
これは、彼の「これまでのところ最高のアイデア」コードに基づいて提供された @ phillip-zyan-k-lee-stockmann の適応です。
彼の(優れた役立つスニペット)からの私の変更は、基本的には次のとおりです。
そして、これが私がcrontab-add-hourly.sh
と呼んだものの私のコードです:
#!/bin/bash
# PURPOSE:
# To allow simple, programmatic addition of commands/entries into the crontab (if not already present)
cmd=$1
entry="0 * * * * $cmd"
printf "we want to add this entry:\n$entry\n\n"
escapedEntry=$(printf '%s\n' "$entry" | sed 's:[][\/.^$*]:\\&:g') #from: https://unix.stackexchange.com/a/129063/320236
printf "but first we'll see if it's already in there using this regex pattern:\n$escapedEntry\n\n"
if [[ $(crontab -l | egrep -v '^(#|$)' | grep -q "$escapedEntry"; echo $?) == 1 ]] # from: https://unix.stackexchange.com/a/297377/320236
then
printf "all clear; pattern was not already present; adding command to crontab hourly:\n$cmd\n\n"
(crontab -l ; printf "$entry\n\n") | crontab -
else
printf "pattern already present; no action taken\n\n"
fi
使用例と出力:
$ ./crontab-add-hourly.sh my-script.bash
we want to add this entry:
0 * * * * my-script.bash
but first we'll see if it's already in there using this regex pattern:
0 \* \* \* \* my-script\.bash
all clear; pattern was not already present; adding command to crontab hourly:
my-script.bash
TL; DR:これは実際に機能し、Bash 4.4でテストされています。
if [[ $(crontab -l | egrep -v "^(#|$)" | grep -q 'some_command'; echo $?) == 1 ]]
then
set -f
printf "$(crontab -l ; echo '* * * * * some_command')\n" | crontab -
set +f
fi
@Phillip -Zyan K Lee- Stockmannの回答のコメントで述べたように、このソリューションは*
現在のディレクトリのすべてのファイルに。コメントの提案が機能しませんでした。 set -fはワイルドカード拡張を無効にします。 https://stackoverflow.com/a/11456496/915441 を参照してください。