Udevイベントで長いプロセスを実行するには?

Udevイベントで長いプロセスを実行するには?

ピアツーピアUSB モデムが接続されると接続が行われるため、次のudev規則を使用します。

ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="16d8",\
    RUN+="/usr/local/bin/newPPP.sh $env{DEVNAME}"

(私のモデムは/devと読みますttyACM0

新しいPPP.sh:

#!/bin/bash
/usr/bin/pon prov $1 >/dev/null 2>&1 &

質問:

イベントudevが発生し、newPPP.shが実行されていますが、newPPP.sh約4〜5秒後にプロセスが終了します。ppp接続する時間はありません(ダイヤルタイムアウトは10秒です)。

死ぬことなくどのように長いプロセスを実行できますか?

試してみましたが、nohupやはり動作しません。

システム: Arch Linux

修正する

解決策が見つかりましたここありがとうございます。マックスシュレプチガー

at nowudevプロセスとは別にジョブを実行するために使用します。

しかし、1つの質問に対する答えはまだ残っています。なぜ動作しnohup&動作しないのですか?

答え1

システムサポートを介してまともなディストリビューションを実行している場合は、最も簡単で技術的に安全な方法は次のようにすることです。機器単位

このように、systemdは長期実行スクリプトを完全に制御し、デバイスがシャットダウン/削除された後にプロセスを適切にシャットダウンすることもできます。プロセスを分離するということは、プロセスの状態と記録のすべての制御を放棄することを意味します。 。

これに加えて、を実行してデバイスと接続されているサービスの状態を確認することもできますsystemctl status my-ppp-thing.device

また、見ることができますこのブログ投稿より多くの例と詳細を確認してください。

答え2

現在、udevはcgroupを使用して作成されたジョブを検索して削除します。 1つの解決策は、「今」または「配置」を使用することです。別の解決策は次のとおりです。ダブルフォークプロセスを別のcgroupに「移行」します。以下はサンプルPythonコードです(同様のコードは任意の言語で書くことができます)。

os.closerange(0, 65535)  # just in case
pid = os.fork()
if not pid:
  pid = os.fork()  # fork again so the child would adopted by init
  if not pid:
    # relocate this process to another cgroup
    with open("/sys/fs/cgroup/cpu/tasks", "a+") as fd:
      fd.write(str(os.getpid()))
    sleep(3)  # defer execution by XX seconds
    # YOUR CODE GOES HERE
sleep(0.1)  # get forked process chance to change cgroup

デバッグ出力は、たとえばシステムログに送信できます。

答え3

私はsetidを使って作業しました。私のudevルールのRUN部分:

RUN+="/bin/bash script.sh"

その後、スクリプトから:

#!/bin/bash
if [ "$1" != "fo_real" ]; then
  /usr/bin/setsid $(/usr/bin/dirname $0)/$(/usr/bin/basename $0) fo_real &
  exit
fi

Rest of script is here....

スクリプトへの最初の呼び出しは終了ステータス 0 を返しますが、スクリプトへの 2 番目の呼び出しは PPID=1 で実行され続けます。

答え4

なぜ死んでいるのかわかりませんが、これがうまくいくことがわかりました。

RUN+="/bin/bash -c 'YOUR_SCRIPT &'"

Bashにバックグラウンドタスクだけを残すと、バックグラウンド自体に入るようです。

関連情報