私ピアツーピア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 now
udevプロセスとは別にジョブを実行するために使用します。
しかし、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にバックグラウンドタスクだけを残すと、バックグラウンド自体に入るようです。