CoreOS에서 실행중인 서버 인스턴스에 대한 검색 보조 서비스를위한 상당히 간단한 단위 파일이 있습니다. 단위 파일은 다음과 같습니다.
[Unit]
Description=Discovery for frontend server (instance %i)
BindsTo=frontend@%i.service
After=frontend@%i.service
[Service]
EnvironmentFile=/etc/environment
ExecStart=/usr/bin/bash -c ' \
while true; do \
export PORT=$(docker port frontend%i 80 | sed s/.*://); \
etcdctl set /services/frontend/%i "${COREOS_PRIVATE_IPV4}:$PORT" --ttl 60; \
sleep 45; \
done'
ExecStop=/usr/bin/etcdctl rm /services/frontend/%i
[X-Fleet]
MachineOf=frontend@%i.service
이것은 잘 작동하지만이 단계에 도달하려면 나이가 걸렸습니다 etcdctl
.
etcdctl set /services/frontend/%i "${COREOS_PRIVATE_IPV4}:${PORT}" --ttl 60; \
그런 다음 작동하지 않습니다- 100.45.218.3:
포트가없는 같은 값을 설정하게됩니다 . 그 과정에서 $PORT
변수 의 다른 용도로 많은 시간을 보냈고 , 내가 설정 한 구성이 왜 작동하는지 전혀 알지 못합니다. 어느 시점에서 나는 이것을 스크립트에서 가지고 있었다.
echo hi $PORT; \
echo "hi $PORT"; \
echo hi ${PORT}; \
echo "hi ${PORT}"; \
그리고 다음과 같은 저널 로그를 얻었습니다.
Aug 17 01:05:07 core-01 bash[53694]: hi 32769
Aug 17 01:05:07 core-01 bash[53694]: hi 32769
Aug 17 01:05:07 core-01 bash[53694]: hi
Aug 17 01:05:07 core-01 bash[53694]: hi
본질적으로 내 질문은 : 여기에서 무슨 일이 일어나고 있습니까? 이것은 내가 {}
bash 스크립트에서 작업 하는 것을 이해하는 방법에 직면합니다 . 왜 난에 중괄호 사용할 수 있습니다 COREOS_PRIVATE_IPV4
에서 수출되는 변수 ( /etc/environment
대한,하지만를 PORT
?
답변
이것은 systemd.service (1)에 문서화되어 있습니다. ${PORT}
systemd에 의해 확장됩니다. 를 전달하려면 $
당신이 쓰기에 필요한 쉘 $$
그래서 $${PORT}
. 중요한 내용은 다음과 같습니다.
리터럴 달러 기호를 전달하려면 “$$”를 사용하십시오. 확장시 값을 알 수없는 변수는 빈 문자열로 처리됩니다.
답변
-
PORT의 내용이 다른 bash 변수에서 나온 경우
indirect reference
다음을 시도하십시오.${!PORT}
-
나는 당신이 당신의 쉘이 Bash라고 확신합니다.