
システムタイマーとドリフトの開始時に多少迷惑な問題があります。近代化しようとしている古いcron.dスクリプト(10分ごとに忠実に実行されます)があります。問題は、開始されたサービスが10分以上実行されているという点だ。 cronを使用すると、これは問題ではありませんでした。しばらくの間両方のインスタンスを実行しましたが、systemdは動作が異なります。
タイマーは次のとおりです。
[Timer]
OnCalendar=*:0/10:0
Persistent=false
AccuracySec=1s
私が知っているのは、このタスクは正確に08:00:00、08:10:00、08:20:00などで実行する必要があります。ただし、開始される関連サービスは10分より少し長く実行されるため、タイマーが実行されるたびに約10秒ずつ徐々にドリフトします。つまり、開始時間は08:00:00、08:10:10、08:20:20などです.タイマーが私が望むように動作するように強制する方法はありますか?
また、バックグラウンドでサービスを実行状態にしてみましたが、監視されていないsystemdが提供していますが、これで多くの成功を収めていませんでした。コマンド全体を別のシェルスクリプトに入れるのとExecStart=/bin/sh -c "/run/my/cmd -options &"
同じことを試しましたが、役に立ちませんでした。すぐに開始または終了nohup
しません。cmd
それでは、システムタイマーを以前のcronスクリプトのように実行するにはどうすればよいですか?唯一の残りのアイデア/解決方法は、間隔が20分に設定された2つのタイマーを作成することですが、それは非常に愚かな考えのように聞こえます。
答え1
このタイプの動作は直接サポートされていないようですsystemd
。これは、実行中のすべてのサービスを追跡する方法によって意味があります。結局、10分ごとに実行されるのではなく、20分ごとに実行される2つの同じサービスを作成する必要がありました。
関連タイマー部分は次のとおりです。
myservice-even.timer
[Timer]
OnCalendar=*:0/20:0
Persistent=false
AccuracySec=1s
そして
myservice - 奇妙なタイマー
[Timer]
OnCalendar=*:10/20:0
Persistent=false
AccuracySec=1s
RuntimeMaxSec=900
また、間違った行動をしても、次のラウンドが適切なタイミングで開始されるように、両方のサービスが含まれていました。
答え2
プロセスを非同期的に(そして他のインスタンスとは無関係に)開始するには、を使用して一時systemd-run
サービス systemd-run
またはスコープ単位を作成できます。デフォルトでは、デバイスの識別名が自動的に生成されます。
つまり、systemd サービス S を使用してsystemd-run
プロセス P を開始できます。systemd-run
Pが完了するのを待ちません(この--wait
オプションを使用しない限り)。プロセスPはサービスSの一部ではありません。そして、サービスSが停止してもプロセスPは終了しない。
必要に--property RuntimeMaxSec=900
応じて、withなどのオプションを使用できる必要がありますsystemd-run
。 (正確に設定できるプロパティはsystemd-run
少し異なります。以前のバージョンのsystemdでは、一時デバイスに多くのプロパティを設定できませんでした。)
提供されたコントロールよりも複雑なコントロールを追加する必要があるcron
場合、または一時サービスユニットが提供できるよりも複雑なコントロールを追加する必要がある場合は、必要な機能を持つ他のタスクスケジューラを見つける必要があります。または、子プロセスを作成し、その状態を監視するサービスを自分で作成します。 :-). (あなたできるそのようなサービスにメッセージを送信するためにまだsystemdタイマーを使用していますが、それほどきれいに見えないようです。わかりやすくするには、サービス自体でタイマーを実装していただくと良いと思います。 )