새 서비스를 생성할 때 systemd "status=203/EXEC" 오류 발생

새 서비스를 생성할 때 systemd "status=203/EXEC" 오류 발생

독립 실행형으로 실행될 때 작동하지만 systemd를 통해 실행될 때 다음 오류가 발생하는 Python 스크립트에 대한 새 서비스를 만들었습니다.

Oct 02 12:17:09 raspberrypi systemd[1]: Started Read pressure And Post to mqtt.
Oct 02 12:17:09 raspberrypi systemd[1]: ReadPressure.service: Main process exited, code=exited, status=203/EXEC
Oct 02 12:17:09 raspberrypi systemd[1]: ReadPressure.service: Unit entered failed state.
Oct 02 12:17:09 raspberrypi systemd[1]: ReadPressure.service: Failed with result 'exit-code'.
Oct 02 12:17:09 raspberrypi systemd[1]: ReadPressure.service: Service hold-off time over, scheduling restart.
Oct 02 12:17:09 raspberrypi systemd[1]: Stopped Read pressure And Post to mqtt.
Oct 02 12:17:09 raspberrypi systemd[1]: ReadPressure.service: Start request repeated too quickly.
Oct 02 12:17:09 raspberrypi systemd[1]: Failed to start Read pressure And Post to mqtt.
Oct 02 12:17:09 raspberrypi systemd[1]: ReadPressure.service: Unit entered failed state.
Oct 02 12:17:09 raspberrypi systemd[1]: ReadPressure.service: Failed with result 'exit-code'.

서비스는 "etc/systemd/system/ReadPressure.service"에 생성됩니다. 실행 권한이 있습니다.

서비스는 다음과 같습니다.

[Unit]
Description=ReadPressure

[Service]
ExecStart=/bin/bash -c 'python3 -u /home/pi/ReadPressure/ReadPressure2AndPostToMqtt.py'
WorkingDirectory=/home/pi/ReadPressure/
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

왜 오류가 발생하는지 아시나요? 운영체제는 라즈비안입니다.

감사해요

답변1

노력하다:

pi@raspberrypi:~ $ systemctl status ReadPressure.service

@Ingo가 의역함시작 시 Thonny에서 Python 프로그램을 시작할 수 없습니다.

오류 메시지(코드=종료, 상태=203/EXEC)는 스크립트 자체 또는 해당 인터프리터가 실행되지 않을 때 자주 표시됩니다.

다음과 같은 이유가 있을 수 있습니다.

  • 잘못된 스크립트 경로(예: /home/py/ReadPressure2AndPostToMqtt.py)

  • 스크립트를 실행할 수 없습니다.

  • Shebang 없음(첫 번째 줄)

  • Shebang의 잘못된 경로(예: /bin/python3)

  • 스크립트의 내부 파일에 대한 액세스 권한이 부족할 수 있습니다.

  • SELinux는 ExecStart 매개변수의 실행을 방지할 수 있습니다. /var/log/audit/audit.log에서 다음 형식의 메시지를 확인 type=AVC msg=audit([...]): avc: denied { execute }하세요 ausearch -ts recent -m avc -i.

  • WorkingDirectory매개변수가 잘못되었습니다.

답변2

또 다른 가능한 원인은 status=203/EXECSELinux일 수 있습니다. 제 경우에는 Python 스크립트를 실행하는 유닛 파일이 있습니다.

[Unit]
Description=LibreNMS SNMP Poller Service
After=network.target

[Service]
ExecStart=/opt/librenms/librenms-service.py -v -d
ExecReload=/bin/kill -HUP $MAINPID
WorkingDirectory=/opt/librenms
User=librenms
Group=librenms
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

Python 스크립트에는 SELinux 유형 설명자가 있으므로 httpd_sys_content_t실행이 허용되지 않습니다. 사용하여 오류를 보았는데 audit2why < /var/log/audit/audit.log다음과 같습니다.

type=AVC msg=audit(1631272189.992:1032): avc:  denied  { execute } for  pid=2873 comm="(rvice.py)" name="librenms-service.py" dev="sda3" ino=714393 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=file permissive=0

        Was caused by:
                Missing type enforcement (TE) allow rule.

                You can use audit2allow to generate a loadable module to allow this access.

결국 보안 컨텍스트를 편집했습니다.

비영구 편집(테스트용):

chcon -t bin_t /opt/librenms/librenms-service.py

영구 편집:

semanage fcontext -a -t bin_t '/opt/librenms/librenms-service.py'
restorecon -Fv /opt/bin/librenms-service.py

답변3

다음과 같이 명령을 인용해야 할 수도 있습니다.

ExecStart="/bin/bash -c 'python3 bla blah'"

답변4

나에게 문제는 실제로 이전에 설치하려고 했던 동일한 이름의 서비스였습니다. 로그에 있는 이전 서비스에 대한 참조를 보면 이것이 문제라는 것을 알 수 있습니다. 이전 서비스를 제거하고 "systemctl daemon-reload"를 실행하면 문제가 해결되었습니다.

관련 정보