我想运行一个点对点连接 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 进程分离的工作。
但有一个问题仍然没有得到解答:为什么有效nohup
而不&
有效?
答案1
答案2
如今,udev 使用 cgroup 来搜索并销毁生成的任务。一种解决方案是使用“现在”或“批量”。另一个解决方案是做双叉并将进程“迁移”到另一个 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
我让它与setsid一起工作。我的 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,但对脚本的第二次调用继续运行,且 PPID = 1。
答案4
不知道为什么它被杀死,但我发现这个有效:
RUN+="/bin/bash -c 'YOUR_SCRIPT &'"
似乎当 Bash 只剩下后台作业时,它本身就会进入后台。