変数にオプションを保存するときのbashエスケープの問題

変数にオプションを保存するときのbashエスケープの問題

変数に文字列が格納されています。これは私が望む結果です...

cmd="--name=cloudflare-ddns \
--hostname=oznu-cloudflare-ddns \
--env=SUBDOMAIN=private \
--env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
--env=QEMU_ARCH=x86_64 \
--env=S6_KEEP_ENV=1 \
--env=S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \
--env=CF_API=https://api.cloudflare.com/client/v4 \
--env=RRTYPE=A 
--env='CRON=*/5 *   *   *   *' --env=PROXIED=false \
--env=ZONE=thebiermans.net \
--env=API_KEY=kka \
--network=host \
--restart=always \
--log-driver=db --runtime=runc --detach=true -t oznu/cloudflare-ddns:latest"

実行できるように変数にどのように保存しますか?

例えば

docker run $CMD

ここに正しいエスケープセットがないため、誤った出力が表示されます。

ベストアンサー1

evalシェルに変数に格納されているシェルコードを評価させるには、特別な組み込みコマンドを使用できます。これは他の多くの言語でも同様です。

cmd="--name=cloudflare-ddns \
--hostname=oznu-cloudflare-ddns \
--env=SUBDOMAIN=private \
--env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
--env=QEMU_ARCH=x86_64 \
--env=S6_KEEP_ENV=1 \
--env=S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \
--env=CF_API=https://api.cloudflare.com/client/v4 \
--env=RRTYPE=A 
--env='CRON=*/5 *   *   *   *' --env=PROXIED=false \
--env=ZONE=thebiermans.net \
--env=API_KEY=kka \
--network=host \
--restart=always \
--log-driver=db --runtime=runc --detach=true -t oznu/cloudflare-ddns:latest"

eval "docker run $cmd"

これは、シェル構文で有効なコードの接続"docker run "と内容を想定しています。この場合、コードを解釈するとパラメータリストを含むコマンドが$CMD実行されます。docker

変数に格納された引数のリストを使用してコマンドを実行するには、配列変数を使用できます。

args=(
  --name=cloudflare-ddns
  --hostname=oznu-cloudflare-ddns
  --env=SUBDOMAIN=private
  --env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  --env=QEMU_ARCH=x86_64
  --env=S6_KEEP_ENV=1
  --env=S6_BEHAVIOUR_IF_STAGE2_FAILS=2
  --env=CF_API=https://api.cloudflare.com/client/v4
  --env=RRTYPE=A
  --env='CRON=*/5 *   *   *   *'
  --env=PROXIED=false
  --env=ZONE=thebiermans.net
  --env=API_KEY=kka
  --network=host
  --restart=always
  --log-driver=db --runtime=runc --detach=true 
  -t oznu/cloudflare-ddns:latest
)

docker run "${args[@]}"

とにかく、bashではリストコンテキストに引用されていないパラメータ拡張を置かないでください。これにより、望ましい効果をほとんど得ることができません。これは、変数の内容を文字に分割し、結果の単語ごと$IFSにファイル名の生成を実行するパーティション+グローブ演算子です。これは、シェル構文トークン化と構文解析とはまったく関係ありません。はいたとえば、引用した部分を識別して解釈します。

おすすめ記事