이 변수 이스케이프는 시스템 단위 파일에서 어떻게 작동합니까? 단위 파일이 있습니다. 단위 파일은 다음과

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}. 중요한 내용은 다음과 같습니다.

리터럴 달러 기호를 전달하려면 “$$”를 사용하십시오. 확장시 값을 알 수없는 변수는 빈 문자열로 처리됩니다.


답변

  1. PORT의 내용이 다른 bash 변수에서 나온 경우 indirect reference다음을 시도하십시오.

    ${!PORT}
  2. 나는 당신이 당신의 쉘이 Bash라고 확신합니다.