如何将“逃生地狱”传递给docker run

时间:2018-08-14 19:36:52

标签: bash powershell docker command-line cmd

我正在尝试从powershell \ cmd将几个命令传递到一个高山容器。问题是:命令具有引号\单引号\转义引号。

示例命令,实际命令为一行,我将其拆分,以便于查看:

docker run neilpang/acme.sh bin/sh -c --%
  "acme.sh --issue --dns dns_azure --dnssleep 10 --force -d "domain";
  openssl pkcs12 -inkey /acme.sh/domain/domain.key -in /acme.sh/domain/domain.cer -export -out pfx -password pass:password;
  curl -X POST -d "{\"certName\":\"certName1\",\"certData\":\"$(tail -n +2 /acme.sh/domain/domain.cer > b64; head -n -1 b64)\"}" url -H Content-Type:application/json;
  curl -X POST -d "{\"certName\":\"certName2\",\"certData\":\"$(openssl base64 -in pfx -out b64; cat b64)\"}" url -H Content-Type:application/json"

我尝试过的事情:

  1. 在整个表达式上使用单引号(在-%之后)返回类似于未关闭的带引号的字符串
  2. 在json周围使用单引号可以很好地工作,但是$()不会得到解释,所以我没有得到正确的输出
  3. 在json之前\之后转义"
  4. 在json之前\之后没有",会导致一些垃圾邮件
  5. 如果没有--%,我永远无法使它工作,但是即使使用--%时,ps似乎也会进行一些字符串操作
  6. 使用cmd进行了一些实验,也没有运气。

我愿意采取任何方式进行这项工作:)

对于那些请求的错误,这是一个示例:

-n: line 1: syntax error: unexpected end of file (expecting ")") # quotes around expression
-p: line 1: syntax error: unterminated quoted string # single quotes around expression
no error, but certData empty # no quotes around json
no quotes in json >> not valid json >> doesnt get parsed # escaped quotes around json

执行我试图在容器内传递的字符串会导致有效的“解决方案”,而试图将它们传递通过docker run则会导致上述各种缺陷。我不确定这些是哪里发生的,这是由powershell(尽管我坚信--%在这里完成工作,并且powershell正确传递了所有内容),docker或bash本身引起的。我最接近使用的是'版本,但是它不评估$()内的表达式,所以出现了问题

2 个答案:

答案 0 :(得分:2)

如果将非常长且非常复杂的命令行转换为Shell脚本,将其打包为自定义映像,然后运行该代码,则会发现引用问题变得更加容易。

Shell脚本,我们称它为run_acme.sh

#!/bin/sh
acme.sh --issue --dns dns_azure --dnssleep 10 --force -d "domain"
openssl pkcs12 \
  -inkey /acme.sh/domain/domain.key \
  -in /acme.sh/domain/domain.cer \
  -export \
  -out pfx \
  -password pass:password
CER_B64=$(tail -n +2 /acme.sh/domain/domain.cer | head -n -1)
curl -X POST \
  --data-binary "{\"certName\":\"certName1\",\"certData\":\"$CER_B64\"}" \
  -H 'Content-Type: application/json'
  url
PFX_B64=$(openssl base64 -in pfx)
curl -X POST \
  --data-binary "{\"certName\":\"certName1\",\"certData\":\"$PFX_B64\"}" \
  -H 'Content-Type: application/json'
  url

Dockerfile:

FROM neilpang/acme.sh
COPY run_acme.sh /bin
CMD ["/bin/run_acme.sh"]

然后,您可以docker build像其他任何自定义图像一样docker run,并将其y包含在内,非常长的命令行将被烘焙到图像的shell脚本中。

答案 1 :(得分:1)

我建议您使用喷溅法使其维护起来更加清洁。注意:我不确定您的shell脚本是否需要转义-d参数周围的引号。

$curl1 = '"{\"certName\":\"certName1\",' +
    '\"certData\":\"$(tail -n +2 /acme.sh/domain/domain.cer > b64; head -n -1 b64)\"}"'
$curl2 = '"{\"certName\":\"certName2\",' +
    '\"certData\":\"$(openssl base64 -in pfx -out b64; cat b64)\"}"'

$dockerArgs = @(
    'run', 'neilpang/acme.sh', 'bin/sh', '-c'
    '"acme.sh --issue --dns dns_azure --dnssleep 10 --force -d "domain";' +
    'openssl pkcs12 -inkey /acme.sh/domain/domain.key -in /acme.sh/domain/domain.cer ' +
        '-export -out pfx -password pass:password;' +
    "curl -X POST -d $curl1 url -H Content-Type:application/json;" +
    "curl -X POST -d $curl2 url -H Content-Type:application/json"""
)
docker.exe @dockerArgs

powershell的转义字符是重音符号`,或者您可以将引号""加倍以转义双引号"`""