【问题标题】:How to pass "escape hell" to docker run如何将“逃离地狱”传递给 docker run
【发布时间】:2019-01-21 17:42:39
【问题描述】:

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

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

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 本身。我最接近工作的是' 版本,但它不会评估$() 内的表达式,所以问题

【问题讨论】:

    标签: bash powershell docker command-line cmd


    【解决方案1】:

    如果您将非常长、非常复杂的命令行转换为 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它,很长的命令行将被烘焙到你图像中的shell脚本中。

    【讨论】:

    • 是的,我想过,但这意味着我需要维护它并弄清楚如何将它上传到 docker hub。另外,我还需要弄清楚其他一些事情,比如如何在 bash 中生成密码(或如何传递变量)。我不完全是一个 linux 人。我真的很讨厌 bash 语法。它令人讨厌。我会试着看看这是怎么回事,谢谢!
    • 好的,这比我的方法容易得多(如 x20)。我认为我低估了我的 linux 知识;)
    【解决方案2】:

    我建议使用 splatting 来使这个维护起来更加干净。注意:我不确定您的 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 转义字符是重音`,或者您可以在引号"" 上加倍以转义双引号"`""

    【讨论】:

    • @4c74356b41 它解决了您的转义问题(大概)。如果没有,您可以更轻松地深入了解引发异常的位置(如异常下划线所示)
    • 谢谢,我会试一试,看看它会把我带到哪里
    猜你喜欢
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    相关资源
    最近更新 更多