내가 원하는 건
일시 중지/종료하기 전에 중지하고 재개 후 다시 시작하려는 시스템 서비스가 있습니다.
시스템 세부정보
시스템 세부정보는 아래와 같습니다.
$ 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.service
Python 스크립트는 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.target
Unit 섹션에 추가하여 일시중단에서 재개합니다 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