成功するまで夜(たとえば、23:00~7:00、しかしそれ以降ではない)に実行したい失敗する可能性のあるプロセスがあります。
考えられる解決策は次のとおりです。
- ヘルパースクリプトを開始するには、23:00にクローンジョブを追加します。
- ヘルパースクリプト内で成功するまでプロセスを再試行するバックグラウンドサブシェルを実行します。
- ヘルパースクリプト自体は、時間が1分ごとにまだ6:59未満であることを確認し、それより遅い場合はサブシェルとすべてのサブシェルを終了します。
しかし、コンピュータが23:00に終了し、23:05に起動すると失敗するため、bashを使用した複雑なプロセス管理が必要になり、毎分目を覚ますファイルをロックする必要があるため、通常はエラーが発生しやすいアプローチです.方法。
そのようなタスクをより簡単に定義して実行できるようにする特別なソフトウェアや類似のソフトウェアはありますか?
答え1
1つの可能なアプローチは、プログラムを5分ごとに実行することです(たとえば)。最初の実行で実行中のプロセスのフラグでファイルを生成し、フラグがあると新しい実行が終了します。また、プログラムが成功するとフラグを付けて追加ファイルを生成し、2番目のファイルがある場合はプログラムを実行しません。プログラムが成功または失敗した場合は、最初のファイルを削除することを忘れないでください。
07:00にcronを実行してプログラムを終了/停止します(そして成功ファイルフラグがある場合は削除)。
答え2
しかし、コンピュータが23:00に終了し、23:05に起動すると失敗するため、bashを使用した複雑なプロセス管理が必要になり、毎分目を覚ますファイルをロックする必要があるため、通常はエラーが発生しやすいアプローチです.方法。
この問題を回避するには、anacron
代わりに使用してください。cron
anacron
私のディストリビューションは、毎日のタスクが1日に1回だけ実行されるようにするために使用されます(Ubuntu 20.04)。
構成ファイルの表示(および日次操作のみ)
/etc/crontab
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
これは安全装置エントリです(anacronがインストールされていない場合)。06:25に毎日スクリプトを実行するしかし、正確に言われたように、システムは06:25にオンにする必要が正常に動作します。
いつanacron
はいインストール後、構成ファイルを見てください。
/etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root
# These replace cron's entries
# Frequency (in days) Delay JobId Command
1 5 cron.daily run-parts --report /etc/cron.daily
毎日起動してから5分ごとにanacron
/etc/cron.dailyでスクリプトを実行します。。したがって、ノートブックを10:00にオンにして15:00に再びオンにすると、毎日のスクリプトは10:00anacron
に開始して5分後に一度だけ実行されます。
Ubuntuのsystemd
代わりにinit
。anacron
/lib/systemd/system/anacron.service
[Unit]
Description=Run anacron jobs
After=time-sync.target
# By default, anacron will not run when no AC power is connected to system.
# If you are using systemd and want to run anacron even when running on
# battery, you should create the following file with the specified content
# and then call "systemctl daemon-reload":
# /etc/systemd/system/anacron.service.d/on-ac.conf:
# [Unit]
# ConditionACPower=
# See /usr/share/doc/anacron/README.Debian for detailed information.
ConditionACPower=true
Documentation=man:anacron man:anacrontab
[Service]
EnvironmentFile=/etc/default/anacron
ExecStart=/usr/sbin/anacron -d -q $ANACRON_ARGS
IgnoreSIGPIPE=false
KillMode=mixed
# Use SIGUSR1 to stop gracefully
KillSignal=SIGUSR1
[Install]
WantedBy=multi-user.target
最後に、/lib/systemd/system/anacron.timer
[Unit]
Description=Trigger anacron every hour
[Timer]
OnCalendar=*-*-* 07..23:30
RandomizedDelaySec=5m
Persistent=true
[Install]
WantedBy=timers.target
頭を空にするには少し精神力が必要です。私は本当に好きです。@ロミオ・ニノフソリューションのシンプルさ。欠点は、5分ごとに確認して終了するため、スケーラビリティに影響を与えることです。
しかし、ラップトップに毎日のバックアップソリューションを実装しました(毎日オンになるのではなく)、それは非常にうまく機能し、起動する前にしばらくオンにすることができました(遅延時間が5分を超えました)。潜在的な新しいバックアップを実行せずに、自分のメールをすばやく確認できます。
anacron -t <configfile>
システム構成ファイルの改ざんを防ぐには、直接指定できます。
より多くの情報を知りたい場合:
man anacron
man anacrontab
答え3
最も簡単な答えは、at
コマンドとコマンドをtimeout
組み合わせることです。
スクリプトのフルパスが次のようになるとします。$HOME/scripts/your-script.sh
基本シェルはbash
スクリプトは、完了に1秒から7時間以上かかることを前提としています。
スクリプトは午前7時に停止する必要があります。
スクリプトのタイムアウトを持つ再試行ループを作成します。$HOME/scripts/retry-your-script.sh
cat << EOF > $HOME/scripts/retry-your-script.sh
#!/bin/bash
success_marker=$HOME/scripts/success_marker
timeout 25200 '
while [[ ! -e "\$success_marker" ]]; do
$HOME/scripts/your-script.sh && touch \$success_marker
sleep 5s
done
'
EOF
chmod a+x $HOME/scripts/retry-your-script.sh
今日23:00に再試行スクリプトを実行してください。$HOME/scripts/retry-your-script.sh
at 23:00 -f $HOME/scripts/retry-your-script.sh
詳細な回答@ロミオ・ニノフそして最初に実装されました。
スクリプトのフルパスが次のようになるとします。$HOME/scripts/your-script.sh
基本シェルはbash
あなたのスクリプトは次の完了時間を前提としています。4分以下。
scriptという名前のcrontabを作成します。$HOME/scripts/croned-your-script.sh
cat << EOF > $HOME/scripts/croned-your-script.sh
#!/bin/bash
source $HOME/.bash_profile
success_marker=$HOME/scripts/success_marker
if [[ ! -e "\$success_marker" ]]; then
$HOME/scripts/timed-your-script.sh && touch \$success_marker
fi
EOF
chmod a+x $HOME/scripts/croned-your-script.sh
crontabクリーンアップスクリプトを生成します。$HOME/scripts/croned-cleanup.sh
cat << EOF > $HOME/scripts/croned-your-script.sh
#!/bin/bash
source $HOME/.bash_profile
success_marker=$HOME/scripts/success_marker
if [[ -e "\$success_marker" ]]; then
crontab -l | sed "/croned-your-script.sh/d" | crontab
crontab -l | sed "/croned-cleanup.sh/d" | crontab
rm -f "\$success_marker"
fi
EOF
chmod a+x $HOME/scripts/croned-cleanup.sh
crontabリストにcrontabスクリプトをリンクします。$HOME/scripts/croned-your-script.sh
crontab -l | sed "1i */4 22-23,0-6 * * * $HOME/scripts/croned-your-script.sh" | crontab
クリーンなcrontabスクリプトをcrontabリストにリンクします。$HOME/scripts/cron-cleanup.sh
crontab -l | sed "1i 1 6 * * * $HOME/scripts/croned-cleanup.sh" | crontab