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}
私はあなたがあなたのシェルがバッシュであると確信していると思います