나는 항상 서비스 A와 관련된 프로그램이 서비스 B보다 먼저 완료되도록 실행해야 하는 상황에 직면합니다. "이후"로는 문제가 해결되지 않습니다. 나중에 말해
가장 중요한 점은 서비스 장치의 경우 구성된 시작 명령이 모두 호출되고 실패하거나 성공적인 시작을 보고하면 Before=/After= 목적에 따라 시작이 완료된 것으로 간주된다는 것입니다. ",그러나 이것이 기본 프로세스가 성공적으로 완료되었음을 의미하지는 않습니다.
제 생각에는 기능에 눈에 띄는 구멍이 있는 것 같습니다. 서비스 B가 서비스 A의 성공적인 완료에 의존하는 경우 서비스 B를 어떻게 시작합니까?
답변1
이 답변내 질문에 거의 명확하게 답변했지만 관련 설명을 생략했습니다 Type=oneshot
. 다음은 관련 텍스트입니다systemd.service 문서.
oneshot은 단순하게 작동하지만 서비스 관리자는 기본 프로세스가 종료된 후 장치를 고려합니다. 그런 다음 후속 장치를 시작합니다.
따라서 일회성 서비스를 사용하여 결정적 정렬을 수행할 수 있습니다.
답변2
이것은 quote를 Requires=
사용할 때 일반적으로 사용하는 고유한 솔루션 입니다 .After=
man systemd.unit
필요=
Wants=와 유사하지만 더 강력한 수요 종속성을 선언합니다. 이러한 유형의 종속성은 유닛 파일과 함께 제공되는 .requires/ 디렉터리에 심볼릭 링크를 추가하여 구성할 수도 있습니다.
이 장치가 활성화되면 나열된 장치도 활성화됩니다. 다른 장치 중 하나가 활성화되지 않고 주문 종속성 After=가 실패한 장치에 설정된 경우 해당 장치는 시작되지 않습니다. 또한 After= 지정 여부에 관계없이 다른 장치 중 하나가 명시적으로 중지(또는 다시 시작)되면 이 장치가 중지(또는 다시 시작)됩니다.
After=
의존하는 장치를 기준으로 장치가 시작되는 시점을 지정하고 Requires=
다른 장치가 성공적으로 시작해야 하는 시점을 정의하면 됩니다.
답변3
타겟의 문제는 닫히는 것을 방해한다는 것입니다. 그렇기 때문에 답을 찾는 것이 그토록 어렵습니다. 권한이 상승 하면 shutdown.target
서비스가 중지되지만 이로 인해 후속 서비스가 트리거됩니다.
첫 번째 직업이 단기 공연이었다면 이를 하나의 서비스로 결합하는 것을 고려해 보세요.Type=simple
, 그리고 실행ExecStartPre=
. 시스템은 첫 번째 작업이 완료될 때까지 보류되며 activating
첫 번째 작업이 성공한 경우에만 두 번째 작업을 실행합니다. 이 스타일은 첫 번째 작업을 두 번째 작업으로 설정해야 하는 경우 유용합니다.
[Service]
ExecStartPre=/path/to/firstjob
ExecStart=/path/to/secondjob
[Install]
WantedBy=multi-user.target
두 번째 작업도 단기 실행인 경우 다음을 사용하세요.Type=oneshot
. 이 경우 둘 다 작동합니다.ExecStart=
.
[Service]
Type=oneshot
ExecStart=/path/to/firstjob
ExecStart=/path/to/secondjob
[Install]
WantedBy=multi-user.target
첫 번째 작업은 단기 실행이 아니지만 두 번째 작업은 단기 실행인 경우 실행을 고려하세요.ExecStopPost=
. 하지만 이 명령은 성공할 수도 있고 실패할 수도 있으니 주의하세요 ExecStart=
. 첫 번째 작업의 성공 여부를 확인하여 두 번째 작업을 스크립트로 래핑하여 조건부로 실행할 수 있습니다. $SERVICE_RESULT
,$EXIT_CODE
그리고$EXIT_STATUS
. 이 예는 두 번째 작업이 정리 작업인 경우 특히 유용합니다.
[Service]
ExecStart=/path/to/firstjob
ExecStopPost=/bin/bash -c "[ $SERVICE_RESULT = success ] && /path/to/secondjob"
[Install]
WantedBy=multi-user.target
두 작업을 모두 실행하는 데 시간이 오래 걸리면 좀 더 창의력을 발휘해야 합니다. 당신이 할 수 있는 한 가지는 트리거를 설정하는 것입니다.*.path
단위. 그러면 자매 서비스가 실행됩니다.PathChanged=
만졌다. 경로에는 고유하고 접두사가 붙은 것을 사용합니다.%t
지정자이 파일을 다음 위치에 넣으세요 /run
.
# A.service
[Service]
ExecStart=/path/to/firstjob
ExecStopPost=/bin/bash -c "[ $SERVICE_RESULT = success ] && touch %t/B.trigger"
[Install]
WantedBy=multi-user.target
# B.path
[Path]
PathChanged=%t/B.trigger
Service=B.service
[Install]
WantedBy=multi-user.target
# B.service
[Service]
ExecStart=/path/to/secondjob
다음 장치가 트리거되기 전에 경로가 중지되므로 종료를 방해하지 않습니다.