systemd가 데몬을 실행하기 전에 심볼릭 링크의 대상을 생성하거나 변경해야 합니다. 데몬은 표준 출력을 이 기호 링크로 리디렉션하고 이를 통해 시작된 각 데몬에 대한 특수 파일로 리디렉션합니다. 이것이 우리가 생각하는 것입니다. "test_start.service"라는 서비스 단위 파일을 설정했습니다.
[Unit]
Description=Test Server
After=network-online.target test_start.socket
Requires=network-online.target test_start.socket
[Service]
User=test1
Group=test1
Type=simple
ExecStartPre=/bin/bash /etc/testServer/Debug/makeOutfile.sh
ExecStart=/etc/testServer/Debug/testServer
StandardInput=socket
StandardOutput=file:/etc/testServer/Debug/test_outLink
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
Bash 스크립트 "/etc/testServer/Debug/makeOutfile.sh"는 다음과 같습니다.
#!/usr/bin/env bash
timeStamp=$(date +%y-%m-%d_%Hh%Mm%Ss)
myfolder="/etc/testServer/Debug"
# create new logfile
touch $myfolder/started_$timeStamp
# remove old symlink if exists (owned by test1)
if [ -h $myfolder/test_outLink ]; then
rm $myfolder/test_outLink
fi
# create new symlink
ln -s $myfolder/started_$timeStamp $myfolder/test_outLink
어떤 경우에는 작동합니다. 심볼릭 링크가 존재하고 그것이 가리키는 파일도 존재한다면 모든 것이 정상입니다. bash 스크립트 "makeOutfile.sh"는 테스트용 터미널과 systemd 서비스 시작을 통해 실행됩니다.
하지만:
(이름: "started_atSomeDate") 가리키는 파일이 존재하지 않는 경우(누군가가 그 동안 삭제했기 때문에) 스크립트의 터미널 호출은 예상대로 작동하지만 systemd 서비스를 시작하면 소유한 추가 파일이 추가됩니다. 원래의 이전 파일 이름이 "started_atSomeDate"인 루트 루트입니다.
이것은 어디에서 왔습니까?
이전 심볼릭 링크 "test_outLink"가 존재하지 않는 경우(누군가가 도중에 삭제했기 때문에) 스크립트의 터미널 호출은 예상대로 작동하지만 systemd 서비스를 시작하면 새로 생성된 "test_outLink"가 일반 파일로 추가됩니다. 루트 그룹이 있는 루트가 소유하고 있으며 서비스를 시작할 수 없습니다.
여기에 심각한 문제가 있습니다. systemd 서비스 단위 사용자와 그룹이 test1인데 여기에 루트가 섞여 있습니다. 누구든지 이것을 설명할 수 있나요? 내가 뭘 잘못했나요?
답변1
내 제안은 쉘 스크립트를 사용하여 로그 파일을 설정해야 한다는 것입니다.그리고적절한 리디렉션으로 테스트 서버를 실행하여 StandardOutput=
귀하의 사례에 적용되지 않는 시스템 설정을 우회하십시오.
다음과 같은 bash 스크립트를 만듭니다 /etc/testServer/Debug/runTestServer.sh
.
#!/usr/bin/env bash
timeStamp=$(date +%y-%m-%d_%Hh%Mm%Ss)
myfolder="/etc/testServer/Debug"
# create new logfile
touch $myfolder/started_$timeStamp
# remove old symlink if exists (owned by test1)
if [ -h $myfolder/test_outLink ]; then
rm $myfolder/test_outLink
fi
# create new symlink
ln -s $myfolder/started_$timeStamp $myfolder/test_outLink
# run the actual testServer
exec /etc/testServer/Debug/testServer >/etc/testServer/Debug/test_outLink
원본 스크립트와의 유일한 차이점 makeOutfile.sh
은 이 스크립트가 testServer
적절한 리디렉션을 사용하여 실행되어 표준 출력을 방금 설정한 로그 파일로 보내는 것입니다.
exec
또한 쉘 스크립트가 유지되거나 대체되지 않도록 하는 데에도 사용됩니다 testServer
(그래서 systemd는 서비스의 주요 프로세스가 무엇인지 알 수 있습니다).
유닛 파일에서 해당 파일을 제거 ExecStartPre=
하고 다음으로 StandardOutput=
교체하세요 ExecStart=
.
ExecStart=/etc/testServer/Debug/runTestServer.sh
(대안으로 스크립트를 호출하는 것도 /bin/bash
가능하지만 스크립트에 실행 가능한 비트가 설정되어 있는 한 반드시 필요하지는 않습니다.)
이와 같은 스크립트로 서버를 설정하면 심볼릭 링크를 완전히 우회하고 최종 started_$timeStamp
로그 파일로 직접 리디렉션할 수도 있습니다.
나는 systemd 코드를 직접 보지 않았으며 문서가 서로 어떻게 상호 작용하는지 정확히 명확하지 않습니다. 하지만 systemd가 단계를 실행하는 순서와 어떤 프로세스가 이를 실행하는지에 확실히 문제가 있습니다 StandardOutput=
. ExecStartPre=
, 이로 인해 권한/소유권이 달라짐) 따라서 귀하가 보고한 결과에 별로 놀라지 않습니다. 어쨌든 내 제안은 단일 래퍼 실행기 스크립트를 사용하여 단순화하는 것입니다. 따라서 문제가 해결되기를 바랍니다.