내가 원하는 건

내가 원하는 건

내가 원하는 건

일시 중지/종료하기 전에 중지하고 재개 후 다시 시작하려는 시스템 서비스가 있습니다.

시스템 세부정보

시스템 세부정보는 아래와 같습니다.

$ lsb_release -dc
Description:    Ubuntu 20.04.1 LTS
Codename:   focal

$ systemd --version
systemd 245 (245.4-4ubuntu3.3)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid

내가 지금까지 가지고 있는 것

일시 중지 및 재개시 Python 프로세스를 myservice-resume.service각각 시작하고 중지하는 두 가지 서비스가 있습니다 . myservice-suspend.servicePython 스크립트는 RGB 조명을 제어하는 ​​SDK 서버에 명령을 실행합니다. on이 매개변수로 전달되면(ExecStart에서와 같이) 루프의 일부로 명령을 계속 실행하려면 프로세스가 백그라운드에서 실행되어야 합니다. 프로세스가 SIGINT 신호를 포착하면 조명이 꺼지고 정상적으로 종료됩니다. 이 설정에서는 myservice-suspens.service가 일시 중단되기 전에 실행되고 충돌로 인해 중지됩니다 myservice-resume.service.

myservice-resume.service

[Unit]
Description=Start myservice-resume.service after suspend and shutdown

[Service]
Type=simple
ExecStart=/path/to/python3 /path/to/script.py on

myservice-suspend.service
[Unit]
Description=Stop myservice-resume.service before suspend and shutdown
Before=suspend.target shutdown.target
Conflicts=myservice-resume.service

[Service]
Type=oneshot
ExecStart=/bin/true

[Install]
WantedBy=suspend.target shutdown.target

이 설정에서는 을 사용하여 서비스(및 조명)를 시작하고 을 사용하여 systemctl start myservice-resume.service조명을 성공적으로 종료 systemctl start myservice-suspend.service하거나 systemctl stop myservice-resume.service를 사용하여 시스템 정지를 수행합니다 systemctl suspend. myservice-resume.service시스템이 다시 시작될 때 첫 번째 서비스가 자동으로 다시 시작되기를 원합니다 . [Unit] 및 [Install] 섹션에 몇 가지 영리한 After/Before/WantedBy 대상을 추가하는 것이 포함될 것이라고 생각하지만 이를 설정하는 적절한 방법을 알 수 없습니다.

연구/내가 시도한 것

관련 게시물(Systemd: 일시 중단 전 서비스 중지, 복구 후 다시 시작)는 서비스가 실행되도록 구성할 수 있음을 의미합니다.뒤쪽에After=suspend.targetUnit 섹션에 추가하여 일시중단에서 재개합니다 myservice-resume.service. 이것을 시도했지만 systemctl 로그에는 복구 시 장치가 다시 시작되지 않는 것으로 표시됩니다.

이 게시물(일시중단/재개를 위한 시스템 단위 파일 작성) 솔루션을 제안하고 After/WantedBy의 목적을 명확히 하기 위해 OP를 systemd 매뉴얼 페이지로 지정했지만 거기에서도 솔루션을 찾을 수 없습니다.

답변1

마지막으로 다음 예에서 After=또는에 대한 필요성을 볼 수 있습니다.Before=아키텍처Linux(늘 그렇듯, 이는 특별한 도움의 원천입니다.) 해당 링크를 기반으로 일시 중지 및 재개 시 명령을 실행하기 위한 두 가지 솔루션이 있습니다.

mysyssuspend한 가지 방법은 및 와 같은 두 개의 단위를 사용하는 것입니다 mysysresume. 다음 예에서는 date명령이 활성화되는 시기를 확인할 수 있도록 syslog에 대한 명령만 실행합니다.

/etc/systemd/system/mysyssuspend.service

[Unit]
Before=suspend.target
[Service]
Type=simple
StandardOutput=syslog
ExecStart=/bin/date +'mysyssuspend start %%H:%%M:%%S'
[Install]
WantedBy=suspend.target

/etc/systemd/system/mysysresume.service

[Unit]
After=suspend.target
[Service]
Type=simple
StandardOutput=syslog
ExecStart=/bin/date +'mysysresume start %%H:%%M:%%S'
[Install]
WantedBy=suspend.target

평소와 같이 유닛 파일을 생성한 후 및 을 수행하십시오 systemctl daemon-reload.systemctl enable mysyssuspend mysysresume

첫 번째 유닛은 Before일시 중지 대상에 의존하며 컴퓨터가 일시 중지 상태가 되면 실행됩니다. 두 번째 유닛에도 After종속성이 있으며 복구 시 실행됩니다.

또 다른 접근 방식은 모든 명령을 하나의 단위에 넣는 것입니다. /etc/systemd/system/mysuspendresume.service

[Unit]
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
StandardOutput=syslog
RemainAfterExit=yes
ExecStart=/bin/date +'mysuspendresume start %%H:%%M:%%S'
ExecStop=/bin/date +'mysuspendresume stop %%H:%%M:%%S'
[Install]
WantedBy=sleep.target

이는 StopWhenUnneeded=yes활성 서비스가 필요하지 않을 때 서비스가 중지되도록 작동합니다. 수면 목표도 있으므로 StopWhenUnneeded완료되면 ExecStop유닛이 실행됩니다. 이는 완료 후에도 RemainAfterExit우리 유닛이 여전히 활성 상태로 간주되도록 하기 위해 필요합니다 .ExecStart

systemd 버전 237을 사용하여 Ubuntu 18.04.5에서 두 가지 방법을 모두 테스트했는데 제대로 작동하는 것 같습니다.


귀하의 요구 사항을 위의 작업 메커니즘에 통합하려고 시도하는 것보다 독립 실행형 장치를 중지/시작하기 위해 이들 중 하나를 사용하는 것이 더 실용적일 수 있습니다. 예를 들어 두 번째 방법을 사용하여 mylongrun서비스를 추가합니다.

/etc/systemd/system/mysuspendresume.service

[Unit]
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
StandardOutput=syslog
RemainAfterExit=yes
ExecStart=-/bin/date +'my1 %%H:%%M:%%S' ; /bin/systemctl stop mylongrun ; /bin/date +'my2 %%H:%%M:%%S'
ExecStop=-/bin/date +'my3 %%H:%%M:%%S' ; /bin/systemctl start mylongrun ; /bin/date +'my4 %%H:%%M:%%S'
[Install]
WantedBy=sleep.target

/etc/systemd/system/mylongrun.service

[Unit]
Description=Long Run
[Service]
Type=simple
StandardOutput=syslog
ExecStart=/bin/bash -c 'date +"my11 %%H:%%M:%%S"; while sleep 2; do date +"my12 %%H:%%M:%%S"; done'
ExecStop=/bin/bash -c 'date +"my13 %%H:%%M:%%S"; sleep 10; date +"my14 %%H:%%M:%%S"'
[Install]
WantedBy=multi-user.target

뚜껑을 시작 하고 닫아 mylongrun이를 테스트하면 다음 Journalctl 항목이 생성됩니다.

09:29:19 bash[3626]: my12 09:29:19
09:29:21 bash[3626]: my12 09:29:21
09:29:22 systemd-logind[803]: Lid closed.
09:29:22 systemd-logind[803]: Suspending...
09:29:22 date[3709]: my1 09:29:22
09:29:22 systemd[1]: Stopping Long Run...
09:29:22 bash[3715]: my13 09:29:22
09:29:23 bash[3626]: my12 09:29:23
09:29:25 bash[3626]: my12 09:29:25
09:29:27 bash[3626]: my12 09:29:27
09:29:29 bash[3626]: my12 09:29:29
09:29:31 bash[3626]: my12 09:29:31
09:29:32 bash[3715]: my14 09:29:32
09:29:32 systemd[1]: Stopped Long Run.
09:29:32 date[3729]: my2 09:29:32
09:29:32 systemd[1]: Reached target Sleep.
09:29:33 systemd[1]: Starting Suspend...

장기 실행 중지 명령( sleep 10)이 올바르게 완료되는 것을 확인할 수 있습니다. 복구 시 장기 실행 명령이 다시 시작됩니다.

09:35:12 systemd[1]: Stopped target Sleep.
09:35:12 systemd[1]: mysuspendresume.service: Unit not needed anymore. Stopping.
09:35:12 systemd[1]: Reached target Suspend.
09:35:12 date[3813]: my3 09:35:12
09:35:12 systemd[1]: Started Long Run.
09:35:12 date[3817]: my4 09:35:12
09:35:12 bash[3816]: my11 09:35:12
09:35:14 bash[3816]: my12 09:35:14
09:35:16 bash[3816]: my12 09:35:16
09:35:18 bash[3816]: my12 09:35:18

관련 정보