私の質問には2つのプログラム(kodiとxscreensaver)が含まれています。他のアプリでもこのような状況が発生したので、より一般的にはApp1とApp2という2つのアプリがあると申し上げます。 App2を起動から終了まで継続的に実行したいのですが、マイコンピュータの横でApp1を頻繁に使用します。時々、出発時にApp1を閉じることを忘れることがあります。 App1が実行されていない場合は、App2をデフォルト設定で実行したいと思います。 App1が実行されている場合は、App2がその動作を変更したいのですが、App1が長時間(たとえば1時間30分)実行されている場合は、App2は通常の設定に戻る必要があります。
私はbashスクリプトとcronやstart-stop-daemonなどの他のものを使ってこれを行うことができると思います。これまでbashのAction_Needed.shというファイルで行ったことは次のとおりです。
#!/bin/bash
# Determine if App1 and App2 are running at the same time
# Exit with 0 if yes, Exit with 1 if not
ps -e | grep -q "App1"
if [ $? -eq 0 ]
then
# App2 should always be running, but check
# anyway. This could potentially be used
# to restart App2 automatically, if for some
# reason it was closed or crashed.
ps -e | grep -q "App2"
if [ $? -eq 0 ]
then
return 0
else
return 1
fi
else
return 1
fi
簡単に言うと、Cronでこのスクリプトを使用して毎分実行し、上記のスクリプトがステータス0で終了したときにApp2の動作を変更できます。
App1が長時間実行されていて(たとえば、1時間半)、App2が正常に実行され続けるようにするにはどうすればよいですか? Cron以外のものを使うべきですか?
答え1
それでは、特定の名前のプロセスを確認し、実行するかどうかと実行期間に基づいていくつかの選択をしたいですか?
プロセスのプロセスIDを見つけるには、出力をgrepするか、コメントにリンクされている例または同様のものをps
使用できます。お使いのシステムに何があっても構いません。 (たとえばDebianのパッケージにあります。)pidof
pgrep
pgrep
procps
あなたが望むもう一つは、ターゲットプログラムの実行時間です。最新のLinuxシステムでは、これを使用してps --no-headers -oetimes $PID
プロセスが開始されてからの時間を秒単位で取得できます。
したがって、次のようになります。
#/bin/sh
target="App1"
# target=$1 # uncoment to take the target from the command line
pid=$(pgrep --oldest "$target")
if [ -n "$pid" ] ; then
time=$(ps --no-headers -oetimes "$pid")
echo "Oldest $target has been running for $time seconds"
if [ "$time" -gt 5400 ] ; then
echo "That's more than 1.5 hours"
fi
fi
ただし、検索結果が複数のプロセスと一致する場合pgrep
(およびpidof
)は複数のPIDを返します。一致を十分に狭くするか(pgrep -f
ここで役に立ちます--newest
)、プログラムのPID出力の1つだけを使用するようにスクリプトを変更して、この問題を何らかの形で処理する必要があります。--oldest
pgrep
答え2
高度なプロセス制御に* shを使用しないでください。本質的に、これはSysVinitの資格を奪います。次のように見えるまで、すべての痛みを伴うエッジケースの失敗に対して常に初期化スクリプトをパッチしてリンクできます。いつもタスクを正しく実行し、次のタスクが来るまで責任を負う必要があります。
systemdはupstartと同様に依存関係のある操作をサポートします。両方とも、以下のようにユーザーGUIを実行するための「ユーザーセッション」モードもあります。