이 변수 이스케이프는 시스템 단위 파일에서 어떻게 작동합니까?


9

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?

답변:


9

이것은 systemd.service (1)에 문서화되어 있습니다. ${PORT}systemd에 의해 확장됩니다. 를 전달하려면 $당신이 쓰기에 필요한 쉘 $$그래서 $${PORT}. 중요한 내용은 다음과 같습니다.

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


고마워요! 이제는 스크립트 자체를 실행하는 동안 변수를 시스템으로 대체하여 대체 할 수 있다는 것을 알지 못했습니다 ...
Daniel Buckmaster

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

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


답변 주셔서 감사합니다! 1. PORT스크립트의 라인에서 오는 export PORT=$(docker ...); bash는 4.2 2. CoreOS 배송
다니엘 Buckmaster에게

당신 ${!PORT}은 당신의 스크립트에서 시도 했습니까 ?
Pat

나는 그것을했고 같은 결과 (빈 문자열)를주는 것 같습니다.
Daniel Buckmaster
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.