Tengo un archivo de unidad bastante simple para un servicio de descubrimiento de compañero para una instancia de servidor que estoy ejecutando en CoreOS. El archivo de la unidad se ve así:
[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
Esto funciona bien, pero me llevó años llegar a esta etapa, porque si cambio la etcdctl
línea a esto:
etcdctl set /services/frontend/%i "${COREOS_PRIVATE_IPV4}:${PORT}" --ttl 60; \
Entonces no funciona, termina configurando un valor como 100.45.218.3:
, sin puerto. En el camino, pasé mucho tiempo jugando con diferentes usos de la $PORT
variable, y no tengo idea de por qué la configuración que decidí funciona. En un momento tuve esto en el guión:
echo hi $PORT; \
echo "hi $PORT"; \
echo hi ${PORT}; \
echo "hi ${PORT}"; \
Y obtuve registros de diario como este:
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
Básicamente mi pregunta es: ¿qué está pasando aquí? Esto va en contra de cómo entiendo {}
trabajar en scripts de bash. ¿Y por qué puedo usar curlies en la COREOS_PRIVATE_IPV4
variable (que se exporta desde /etc/environment
, pero no para) PORT
?
si el contenido de PORT proviene de alguna otra variable bash con la que estaría tratando
indirect reference
, intente:Supongo que estás seguro de que tu caparazón es Bash
fuente
PORT
proviene de una línea en el scriptexport PORT=$(docker ...);
2. CoreOS se envía con bash 4.2${!PORT}
en tu script?