Udev 이벤트에서 장시간 프로세스를 실행하는 방법은 무엇입니까?


11

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&일하지?

답변:


11

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

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

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

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


6

요즘 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로 전송 될 수 있습니다.


1
udev가 생성 된 프로세스를 파괴하기 위해 왜 그런 길이로 갈까요?
user30747

udev로 시작한 프로그램이 데몬을 차단하기 때문에 (예를 들어 udev 규칙을 외부 디스플레이에 연결하면 장기간 실행되는 프로그램으로 인해 새 디스플레이가 실제로 사용되는 것을 막을 수 있음) 추측합니다. 나는 그 자체의 기술적 추론을 가지고 있다고 확신하지만, 생성 된 프로세스는 시스템의 주요 부분을 차지할 수 있고 종료되어야 함을 의미합니다.
tobek 2016

2

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

(

lots of code

) &

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


이러한 상황에서 stderr, stdout 및 stderr을 경로 재 지정할 수 있습니다.
mdpc

@mdpc 흠 ... 왜? 이 시나리오에서 usb_modeswitch가 스트림을 닫는 것을 보았습니다 : exec 1 <&-2 <&-5 <&-7 <&
user42295

1

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


0

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.