sigma_devsecops
@sigma_devsecops

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

EC2のuser dataで$を使いたい

解決したいこと

EC2インスタンスの起動時に指定できるuser_dataで$を含む文字列を入れるとうまく動作しません。

発生している問題・エラー

$の使用を知るためにserviceファイルの中で3パターン$を入れてみる

#!/bin/bash
yum install -y docker
cat <<EOF2 > /etc/systemd/system/docker.httpd.service
[Unit]
Description=httpd Container
After=docker.service
Requires=docker.service
[Service]
Environment="CONTAINER_NAME=httpd-container"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker stop $${CONTAINER_NAME} ☆
ExecStartPre=-/usr/bin/docker rm $$${CONTAINER_NAME} ☆
ExecStartPre=/usr/bin/docker pull httpd
ExecStart=/usr/bin/docker run --rm --name "${CONTAINER_NAME}" -p 80:80 httpd ☆
[Install]
WantedBy=multi-user.target
EOF2
systemctl enable --now docker.httpd
systemctl restart docker.httpd
systemctl daemon-reload

結果↓全部だめ

[Unit]
Description=httpd Container
After=docker.service
Requires=docker.service
[Service]
Environment="CONTAINER_NAME=httpd-container"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker stop 2224{CONTAINER_NAME}
ExecStartPre=-/usr/bin/docker rm 2224
ExecStartPre=/usr/bin/docker pull httpd
ExecStart=/usr/bin/docker run --rm --name "" -p 80:80 httpd
[Install]
WantedBy=multi-user.target

適切に$を投入できるようにする方法を探しています。${CONTAINER_NAME}のようにしたいです。
ご存知の方がいらっしゃればご享受いただけると幸いです。

(まあ,dockerをEC2の中で使うならばそもそもECS使えば良いんですが)

0

2Answer

$ がうまく動作しないのは EC2 とは関係ありません。 cat <<EOF2EOF2 の中の文字列に含まれる $ が Bash によって変数展開されているせいです。 ${CONTAINER_NAME} は未定義なので空文字列に、 $$ はプロセス ID に展開されます。

変数展開を防ぐために cat <<'EOF2'EOF2 と書く(つまり << の後のマーカーをシングルクォートで囲む)と解決します。

2Like

Comments

  1. できました!ありがとうございます。EOFをシングルクォートで囲むとマーカで囲んだ部分全体の変数展開無効にできるんですね。かっこいいワザすぎます。

  2. 将来、変数展開も織り交ぜて使いたいということが出ると思うので、エスケープも覚えておくといいと思います。
    バックスラッシュ(もしくは円マーク)でエスケープできます。

    ExecStartPre=-/usr/bin/docker stop \${CONTAINER_NAME}
    ExecStartPre=-/usr/bin/docker rm \${CONTAINER_NAME}
    

    $$のように重ねて書くのもエスケープの一種ですね。

$はそれぞれ一つで良くないですか?

ExecStartPre=-/usr/bin/docker stop ${CONTAINER_NAME}
ExecStartPre=-/usr/bin/docker rm ${CONTAINER_NAME}

1Like

Comments

  1. コメントありがとうございます。
    一個だとterraform plan実行時にエスケープしろというエラーが出たので
    二個書いてますがうまく言ってないです
    Error: Invalid reference

    │ on test.tf line 19, in resource "aws_instance" "example":
    │ 19: ExecStartPre=-/usr/bin/docker stop ${CONTAINER_NAME}

    │ A reference to a resource type must be followed by at least one
    │ attribute access, specifying the resource name.

Your answer might help someone💌