나는피어 투 피어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
역시 작동하지 않습니다.
시스템: 아치 리눅스
고쳐 쓰다
at now
udev 프로세스와 별도로 작업을 실행하는 데 사용합니다 .
그러나 한 가지 질문에 대한 답은 여전히 남아 있습니다. 왜 작동 nohup
하고 &
작동하지 않습니까?
답변1
시스템 지원을 통해 괜찮은 배포판을 실행하는 경우 가장 쉽고 기술적으로 안전한 방법은 다음을 사용하는 것입니다.장비단위.
이런 방식으로 systemd는 장기 실행 스크립트를 완전히 제어할 수 있으며 장치가 종료/제거된 후 프로세스를 적절하게 종료할 수도 있습니다. 프로세스를 분리한다는 것은 프로세스 상태와 기록에 대한 모든 제어를 포기한다는 의미입니다. .
이 외에도 를 실행하여 장치 및 연결된 서비스의 상태를 확인할 수도 있습니다 systemctl status my-ppp-thing.device
.
당신은 또한 볼 수 있습니다이 블로그 게시물더 많은 예시와 세부정보를 확인하세요.
답변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
나는 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을 반환하지만 스크립트에 대한 두 번째 호출은 PPID = 1로 계속 실행됩니다.
답변4
왜 죽었는지 모르겠지만 이것이 효과가 있다는 것을 알았습니다.
RUN+="/bin/bash -c 'YOUR_SCRIPT &'"
Bash에 백그라운드 작업만 남겨두면 백그라운드 자체로 들어가는 것 같습니다.