/etc/rc.local
CLI를 통하지 않고 systemctl을 통해 활성화할 때 systemd를 사용하여 실행하는 경우 이들 프로그램의 차이점이 무엇인지 궁금합니다 .
예를 들어, 저는 최근 Raspberry Pi에서 hairport-sync를 사용했습니다. 처음에는 sudo systemctlenabled hairport-sync를 통해 시작되도록 hairport-sync를 설정했습니다.
나중에 기능 중 하나를 사용하여 shairport-sync
스크립트를 사전 실행하고 연결된 장치에 게시했습니다.
놀랍게도 스크립트 는 shairport-sync
또는kill
arecord
aplay
그런데 터미널을 통해 스크립트를 실행하면 스크립트가 실행되고 종료되고 arecord
, aplay
.
나 자신을 더욱 혼란스럽게 만들기 위해 shairport-sync
터미널을 통해 종료하고 시작하여 무슨 일이 일어나고 있는지 확인했습니다. 이렇게 하면 장치가 연결되고 종료될 때 예상한 대로 스크립트가 arecord
실행됩니다 aplay
. 그래서 수정으로 이를 비활성화 shairport-sync
하고 빠른 수정으로 실행되도록 설정했습니다 sysmtectl
. /etc/rc.local
그 후에 reboot
는 예상대로 작동했습니다.
systemd
이로 인해 독립 실행형으로 실행되는 프로그램과 CLI를 통해 실행되는 프로그램 사이에 약간의 차이가 있다고 믿게 되었습니다 ./etc/rc.local
왜 이런 일이 발생합니까? 런레벨이 다르기 때문인가요? 어둠의 마법?
장치가 연결될 때 실행되는 스크립트는 shairport-sync
다음과 같습니다.shairportstart.sh
#!/bin/sh
/usr/bin/sudo /bin/pkill arecord
if [ $(date +%H) -ge "18" -o $(date +%H) -le "7" ]; then
/usr/bin/amixer set Speaker 40%
else
/usr/bin/amixer set Speaker 100%
fi
/home/pi/shScripts/shairportfade.sh&
exit 0
페이드 스크립트는 다음과 같습니다.shairportfade.sh
#!/bin/sh
/usr/bin/amixer set Speaker 30-
for (( i=0; i<30; i++))
do
/usr/bin/amixer set Speaker 1+
done
exit 0
장치 연결이 끊어질 때 실행되는 스크립트 shairport-sync
는 다음과 같습니다.shairportend.sh
#!/bin/sh
/usr/bin/amixer set Speaker 70%
/usr/bin/arecord -D plughw:1 -f dat | /usr/bin/aplay -D plughw:1 -f dat&
exit 0
/var/log/syslog
hairport-sync가 CLI에서 처음 실행될 때 systemd
.when 으로 실행되었거나 오류가 없는 경우에만 해당됩니다 .shairport-sync
/etc/rc.local
Jan 24 00:38:45 raspberrypi shairport-sync[617]: sudo: no tty present and no askpass program specified
유일한 차이점은 shairport-sync
처음 시작되는 방식과 장치가 연결되거나 연결 해제될 때 계속 실행되는 방식입니다 shairport-sync
.
답변1
변형"systemd에서 상황이 다르게 동작하는 이유는 무엇입니까?"자주 묻는 질문입니다.
systemd가 아닌 CLI에서 무언가를 실행할 때마다 차이점을 설명할 수 있는 광범위한 가능성이 있습니다.
- 다양한 환경 변수. 해당 섹션에서
systemd
전달되는 환경 변수를 기록합니다.man systemd.exec
생성된 프로세스의 환경 변수. 차이점을 직접 확인하려면 를 사용하면systemd-run /path/to/binary
마치 systemd 서비스에서 실행되는 것처럼 임시 범위에서 애플리케이션을 실행할 수 있습니다. 다음과 같은 출력이 표시됩니다 . 그러면 출력을 볼Running as unit: run-u160.service
수 있습니다 .journalctl -u run-u160.service
수신하는 환경 변수를 덤프하도록 애플리케이션을 수정하고 CLI 실행을 systemd 실행과 비교하십시오. 애플리케이션이 쉽게 수정되지 않는 경우systemd-run env
전달될 환경 변수를 살펴보고 생성된 로깅을 확인할 수 있습니다. X11 GUI 응용 프로그램을 실행하려고 하면,DISPLAY
환경 변수를 설정해야 합니다.. 이 경우 데스크톱 환경의 '자동 시작' 기능을 대신 사용해 보세요systemd
. - 리소스 제한. 바라보다
man systemd.resource-control
리소스 소비를 제한하는 데 사용되는 구성 값입니다.systemctl show your-unit-unit.service
시작하려는 서비스에 영향을 미치는 전체 구성 값을 확인하는 데 사용됩니다 . - 비대화형 쉘. 귀하의
bash
CLI 환경은대화형 로그인 셸..bashrc
이전에는 없었던 소스 파일이 있습니다 .systemd
환경 변수 설정 외에도 이러한 스크립트는 SSH 작업에 로그인이 필요하지 않도록 SSH 에이전트에 연결하는 등의 다른 많은 작업을 수행할 수 있습니다. 당신은 또한 볼 수 있습니다로그인 쉘과 비로그인 쉘의 차이점은 무엇입니까? - 텔레타이프 없음. 대화형 세션은 일부 프로그램에서 비밀번호를 입력하라는 메시지가 표시될 때 사용할 것으로 예상되는
sudo
TTY 에 연결됩니다 .ssh
당신은 또한 볼 수 있습니다sudo: tty가 존재하지 않으며 Askpass 프로그램이 지정되지 않았습니다. - 상대 경로와 절대 경로. 상대 바이너리는 셸에서 작동하지만에 기록된 대로
man systemd.service
의 경우 첫 번째 매개변수는ExecStart=
바이너리 파일의 절대 경로여야 합니다. - 제한된 명령줄 구문. Shell CLI는 다양한 메타 문자를 지원하며
systemd
명령줄 구문은 매우 제한적입니다.. 필요에 따라systemd
셸을 통해 명시적으로 명령을 실행하여 셸 구문을 복제할 수 있습니다.ExecStart=/bin/bash -c '/my/bash $(syntax) >/goes-here.txt'
이는 리소스 제어를 통해 일관된 환경에서 코드를 실행하는 시스템의 기능입니다. 장기적으로 이는 하드웨어에 부담을 주지 않으면서 반복 가능하고 안정적인 결과를 얻는 데 도움이 됩니다.