프로그램은 rc.local에서 시작하지만 아무 작업도 수행하지 않습니다.

프로그램은 rc.local에서 시작하지만 아무 작업도 수행하지 않습니다.

msqllib를 사용하는 프로그램이 있습니다. 내가 만든 일부 하드웨어를 스캔한 다음 mysql 데이터베이스를 업데이트합니다. 이 프로그램은 수년 동안 실행되어 왔지만 시스템 재부팅 시 자동으로 시작할 수 없었습니다. 이제 제어할 수 없는 전원 순환 문제가 발생하여 자동으로 실행되도록 하고 싶습니다.

rc.local에는 다음이 있습니다.

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
/home/nigel/scan
exit 0

이제 명령 프롬프트에 코드를 입력하고 데이터베이스를 업데이트하면 코드가 제대로 실행됩니다. 그러나 rc.local에 넣으면 다음과 같이 ps -ef 표시됩니다.

root       356   350  0 20:54 ?        00:00:03 /home/nigel/scan

그러나 프로그램은 데이터베이스를 업데이트하기 위해 SQL 호출을 수행하지 않습니다.

rc.local의 상태에 대해 묻는다면:

root@Pi-Scan:~# systemctl status rc-local.service
● rc-local.service - /etc/rc.local Compatibility
   Loaded: loaded (/lib/systemd/system/rc-local.service; enabled-runtime; vendor preset: enabled)
  Drop-In: /usr/lib/systemd/system/rc-local.service.d
           └─debian.conf
           /etc/systemd/system/rc-local.service.d
           └─ttyoutput.conf
   Active: activating (start) since Sat 2023-05-06 20:54:19 EDT; 12min ago
     Docs: man:systemd-rc-local-generator(8)
Cntrl PID: 350 (rc.local)
    Tasks: 2 (limit: 414)
      CPU: 3.903s
   CGroup: /system.slice/rc-local.service
           ├─350 /bin/sh -e /etc/rc.local start
           └─356 /home/nigel/scan

May 06 20:54:21 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected
May 06 20:54:22 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected
May 06 20:54:23 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected
May 06 20:54:24 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected
May 06 20:54:25 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected
May 06 20:54:26 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected
May 06 20:54:27 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected
May 06 20:54:28 Pi-Scan rc.local[356]: error: first parameter is not a valid address family: Transport endpoint is not connected

systemctl restart rc-local.service 그러나 프로그램의 두 번째 인스턴스를 실행하면 제대로 작동합니다!

이것이 경쟁 조건일지도 모른다고 생각하여 명령 앞에 sleep 5를 추가하려고 시도했지만 여전히 같은 문제가 발생했습니다.

답변1

댓글 주의해주세요

# This script is executed at the end of each multiuser runlevel.

더 이상 완전히 사실이 아닐 수도 있습니다.

이는 클래식 SysVinit을 사용하고 모든 시작 스크립트가 엄격하게 순차적으로 실행되는 경우에 해당됩니다. 그러나 더 많은 병렬성을 추가하기 위해 시작 스크립트를 처음 재설계한 후, 특히 SysVinit가 systemd로 교체된 후 이는 더 이상 보장되지 않습니다 rc.local.시작 프로세스.

rc-local.servicesystemd가 시작만 해야 한다고 명시적으로 지시하지 않는 한뒤쪽에귀하의 데이터베이스는 실행 중이며 네트워크가 가동되자마자 실행될 것입니다(보통 /usr/lib/systemd/system/rc-local.service.d/debian.conf순서 제약 조건이 적용됨 After=network-online.target).

MySQL 데이터베이스에는 동일한 정렬 제약 조건이 있을 가능성이 높으므로 rc-local.service데이터베이스와 데이터베이스가 동시에 병렬로 시작되어 서로 효과적으로 경쟁할 가능성이 높습니다. 데이터베이스를 시작하는 데 5초 이상이 걸리기 쉬우므로(특히 RasPi의 경우) rc-local.service경주에서 "승리"하고 데이터베이스가 아직 완전히 실행되지 않았을 때 데이터베이스에 연결을 시도하는 것이 가능합니다 .

/home/nigel/scan오류 처리 코드를 개선하면 도움이 될 것 같습니다 . 반복되는 Transport endpoint is not connected오류는 프로그램이 데이터베이스에 대한 연결을 열려고 시도하고 있음을 나타냅니다.실패 사실을 무시하라, 그런 다음 처음에 성공적으로 열리지 않았던 연결을 통해 일부 데이터를 전송하려고 계속 재시도합니다. 이러한 시도는 이미 실패할 운명입니다. 재시도가 필요한 주요 부분은열린 연결, 아니요데이터를 보내다.

답변2

telcoM의 탁월한 답변을 확장하려면(IMHO 최소한 투표하고 동의해야 합니다!):

이 문제를 해결하는 가장 간단한 방법은 고대의 rc.local 메커니즘을 사용하는 것이 아니라 hardware-scan서비스 파일을 생성하고 이미 시작된 데이터베이스 서버에 종속되게 만드는 것입니다. 그러면 종속성이 준비되자마자 필요한 작업이 시작되지만 더 빨리 시작되지는 않을 것입니다.

[Unit]
Description=Scan the hardware using "scan"
# I'm assuming the service is called mariadb.service, but you can check that:
# systemctl status mariadb
# should show it running; if it says that the service couldn't be found,
# try mysql.service instead (I really don't know what you've installed)
After=mariadb.service

[Service]
Type=oneshot
ExecStart=/home/nigel/scan

[Install]
WantedBy=multi-user.target

/etc/systemd/system/에 넣고 다음 부팅 시 시작하려면 hardware-scan.service실행하세요 .sudo systemctl enable hardware-scan

루트로 실행된다는 점에 유의하세요!

관련 정보