Udev 이벤트에서 장시간 프로세스를 실행하는 방법은 무엇입니까? RUN+=”/usr/local/bin/newPPP.sh $env{DEVNAME}” (내 모뎀은 /dev로 나타납니다 ttyACM0) newPPP.sh : #!/bin/bash /usr/bin/pon

USB 모뎀이 연결되어있을 때 ppp 연결 을 실행하려고 하므로이udev 규칙을 사용합니다 .

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

(내 모뎀은 /dev로 나타납니다 ttyACM0)

newPPP.sh :

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

문제:

udev이벤트가 발생, 그리고 newPPP.sh가 실행되고 있지만, newPPP.sh과정은 ~ 4-5s 후 살해된다. ppp연결할 시간이 없습니다 (전화 접속 시간은 10 초입니다).

어떻게 오랜 시간 동안 프로세스를 실행할 수 있습니까?

을 사용해 보았지만 nohup작동하지 않았습니다.

시스템 : 아치 리눅스

최신 정보

maxschlepzig 덕분에 여기 에서 해결책 을 찾았습니다 .

at nowudev 프로세스에서 분리 한 작업을 실행 하는 데 사용 합니다.

그러나 하나 개의 질문은 답이 남아있다 : 왜 nohup&일하지?



답변

시스템 지원을 통해 적절한 배포를 수행하는 경우 가장 쉽고 기술적으로 가장 안전한 방법은 장치 장치 를 사용하는 것 입니다.

이런 방식으로 systemd는 장기 실행 스크립트를 완전히 제어 할 수 있으며 장치가 종료 / 제거 된 후 프로세스를 올바르게 종료 할 수도 있습니다. 프로세스를 분리하면 프로세스 상태를 완전히 제어 할 수 있다는 의미입니다. 그리고 그 역사.

그 외에도을 실행하여 장치의 상태와 연결된 서비스를 검사 할 수 있습니다 systemctl status my-ppp-thing.device.

더 많은 예제와 세부 사항 은 이 블로그 게시물 을 참조하십시오.


답변

요즘 udev는 cgroup을 사용하여 생성 된 작업을 찾아 파괴합니다. 한 가지 해결책은 “지금”또는 “일괄 처리”를 사용하는 것입니다. 또 다른 해결책은 이중 포크 를 수행 하고 다른 cgroup으로 프로세스를 “이동”하는 것입니다. 다음은 파이썬 코드의 예입니다 (유사한 코드는 모든 언어로 작성 될 수 있음).

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

디버그 출력은 예를 들어 syslog로 전송 될 수 있습니다.


답변

셸에는 백그라운드에서 명령을 실행할 수있는 기능이 있습니다.

(

lots of code

) &

괄호로 묶은 명령은 앰퍼샌드로 묶은 후 서브 쉘에서 비동기식으로 실행됩니다. USB 모뎀을 삽입하고 전환 할 때이 기능을 사용하여 자동 연결합니다. 약 20 초가 걸리며 udev에서 잘 작동합니다.


답변

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로 계속 실행됩니다.


답변

아마도 부모 프로세스가 종료되고 종료 신호가 자식으로 전파되어 차단하지 않으며 (아직도 불가능한 경우 SIGKILL) 가능합니다.


답변