配布スクリプトがあります。ユーザーに何かを追加する必要がありますcrontab
(ログをクリーンアップするスクリプトをトリガーします)。XXX(1)ただし、これは初期展開中または更新が必要な場合にのみ実行できます。
(私は走っxxx.py deploy env
たりxxx.py update env
。)
だから私はこうする必要があります:
私のcronJobがすでに存在していることを確認してください。
私のcronJobがまだ存在しない場合は、送信してください。コマンドパラメータの1つが異なる場合は、
私のcronJobを更新してください。
crontab
ファイルを使用しcrontab -e
たり手動で編集したりすることなく、crontab
アイテムを追加/確認/削除(ダウンロード、再作成、再アップロード)する方法がわかりません。
PS:これはユーザー固有のcronjobです。 "webadmin"はこれを行いますが、sudo
これには使用しないでください。
答え1
これまで私の最高のアイデア
まず、コンテンツが必要なものと一致することを確認し、そうでない場合は更新してください。
if [[ $(crontab -l | egrep -v "^(#|$)" | grep -q 'some_command'; echo $?) == 1 ]]
then
set -f
echo $(crontab -l ; echo '* 1 * * * some_command') | crontab -
set +f
fi
しかし、これはクローン操作を中心に別々のスクリプトを書く必要があるほど複雑になります。
他のアイデア
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 2>&1)" | crontab -
# via ssh
echo "$(echo '* 1 * * * some_command' ; ssh user@host crontab -l 2>&1)" | ssh user@host "crontab -"
答え2
記録のためにルートだけがここでファイルに書き込むことができますが、エントリはすべてのユーザーとして実行するように設定できます(実行時には/etc/cron.d/
必要ありません)。この例では、毎週日曜日の真夜中にユーザーとして実行されるsudo
ジョブを定義します。my_webadmin
/usr/local/bin/tidy_logfiles
webadmin
echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' >/etc/cron.d/my_webadmin
重要なのは、my_webadmin
すべてのインストールパッケージがここにファイルを書き込むことができ、競合を避けたいので、ユーザーに固有でなければならないことです(実行時に必ず一意である必要はありません)。この一意性制約を使用すると、my_webadmin
「あなたのもの」であり、他の人のアイテムが含まれていないことを知り、簡単なオーバーライドで更新できます。
また、このアプローチを使用すると、cronエントリを削除するのが簡単になります。
rm -f /etc/cron.d/my_webadmin
質問の範囲外である可能性がありますが、rootアカウントへのリモートアクセス(または経由sudo
)がある場合は、リモートで設定することもできます。
echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' > ~/webadmin.cron
scp -p ~/webadmin.cron root@remote_host:/etc/cron.d/my_webadmin
または、
echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' |
ssh -q root@remote_host 'cat >/etc/cron.d/my_webadmin'
構成を削除し、
ssh -nq root@remote_host rm -f /etc/cron.d/my_webadmin
scp
(パスワードベースのログインを防ぐためにルートアカウントが制限されているため、/コマンドにrootパスワードを提供できないことがよくあります。ssh
代わりに公開/秘密鍵証明書を設定する必要があります。ローカルアカウント(何に関係なく) )リモートサーバーへのフルルートアクセス権を持ちます。 )
答え3
この目的のためには、直接実行するよりもAnsible *を使用することをお勧めします。またはPuppetまたはChef - しかし、Ansibleはこのようなゼロインフラストラクチャ展開スクリプトに適しています。
これは、これらの問題を解決するために設計されたモジュールがすでに存在し、構成管理ツールがすでに等級デフォルトの設計目標として、誤って(または意図的に)再実行しても、必要なときにのみ変更してください。
特にアンサーブルスケジュールされた作業モジュールユーザーのcrontabを変更できます。ボーナスで後でシステムcrontabを使用するように調整したい場合は、書き換えではなく非常に簡単な調整を行うだけです。
*免責事項:私はRed Hatで働いており、AnsibleはRed Hatが後援するプロジェクトです。
答え4
この適応は何ですか?@phillip-zyan-k-lee-stockmann彼の「まだ最高のアイデア」に基づいて提供されたコードです。
彼の(素晴らしいと便利な作品)への私の変更は基本的に次のとおりです。
- 正規表現は、コマンド名だけでなく、時間文字列を含む項目全体に対しても機能します。これにより、同じ名前のコマンドがある場合や、別の項目に名前が重複している場合でも、コマンドの追加をサポートできます。 (まだ同じスケジュールに同じコマンドを2回追加しません。)
- 少しロギング
- さまざまな理由で時間ごとに名前を変更しました。 crontabの構文に基づいて簡単に調整できます。
これが私が言うコードです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