0

对于容器的 Azure Web 应用程序,我需要传递一个带引号的az webapp config set --startup-file. 例如,参数需要包含空格

TL; 博士

  • 这真的应该有效,因为--startup-file只是被附加到docker run一个 docker[COMMAND]上。
  • 奇怪的是,嵌套引用(ie --startup-file "Rscript -e '1+1'") 会导致内部引号的奇怪引号(R 将 接收[EXPR]为 string [1] "1+1")。
  • 任何带有空格的东西,无论是否引用,都会被分解Rscript(或docker run?)的单独参数,因此会失败。

我不清楚在后端使用 引用 Azure 做了什么--startup-file,因为记录docker run的 s 看起来都很好。一方面,Azure 似乎引用了太多(导致字符串),但另一方面又不够(因为空格仍然会破坏内容)。


背景

我假设它实际上--startup-file 可以容纳任意 shell 命令(不仅仅是可执行文件),因为:

  1. 它被不同地描述为“启动命令”和“启动文件portal.azure.com
  2. 根据日志,它只是被附加到docker runas[COMMAND]并且因此应该遵守相同的语义。
  3. 有效(除非有空格)。

我知道潜在的问题是 shell 参数是空格分隔的,但是,如下所示,简单"地不要这样做。

我在Rscript -e "1 + 1"这里用作示例是因为 a) R 是我的用例 b) 很容易看出哪里出了问题。 Rscript是批处理 R 的二进制文件,语义类似于sh -c "pwd;ls". 我猜测可以为sh -c-type 启动文件编写类似的可重现示例。

下面的示例都不会启动 http 服务器,因此会失败az webapp restart,但是启用容器日志记录后,很容易看出已经出了什么问题。(实际用例是Rscript -e "shiny::runApp()"启动一个http 服务器。)

基线

作为基线,这是对应的docker run,它在本地工作得很好(macOS 10.15.6,Docker 版本 19.03.12,构建 48a66213fe):

docker run rstudio/r-base:4.0.2-xenial Rscript -e "1 + 1"
# [1] 2
# works as expected

嵌套报价

az webapp config set --name hello-shiny \
  --startup-file "Rscript -e \"1+2\""
az webapp config set --name hello-shiny \
  --startup-file 'Rscript -e "1+3"' 
az webapp config set --name hello-shiny \
  --startup-file "Rscript -e '1+4'"

根据 Azure 日志,上述各项的对应docker run内容类似于:

docker run -d -p 8409:3838 \
  -e WEBSITES_ENABLE_APP_SERVICE_STORAGE=true \
  -e WEBSITE_SITE_NAME=hello-shiny \
  -e WEBSITE_AUTH_ENABLED=False \
  -e PORT=3838 \ 
  -e WEBSITE_ROLE_INSTANCE_ID=0 \
  -e WEBSITE_HOSTNAME=hello-shiny.azurewebsites.net \ 
  -e HTTP_LOGGING_ENABLED=1 \
  rocker/shiny:4.0.2 \
  Rscript -e "1+2" 

(我已经放弃了一些-e)。如前所述,这是一个有效的docker run调用。如果在本地运行(见上文),它会按预期产生:

# [1] 3

但在 Azure 上,您将参数作为 R 中的字符串获取,如下所示,每个变体

# [1] "1+2"

这很奇怪,因为它表明 azure 以某种方式用另一组引号包围了这个论点。要在本地重现它,您需要运行

docker run rstudio/r-base:4.0.2-xenial Rscript -e "'1+1'"
# [1] "1+1"

显然不是我想要的,以及(我认为?)无证的天蓝色行为。

没有引号,没有空格(有效!)

果然,传递不带引号(和空格)的参数是有效的:

az webapp config set --name hello-shiny \
  --startup-file "Rscript -e 1+7"

产量[1] 8

这并不奇怪,因为两者

  • docker run rstudio/r-base:4.0.2-xenial Rscript -e "1+1"
  • docker run rstudio/r-base:4.0.2-xenial Rscript -e 1+1工作,

因为-e [EXPR]这里不需要习惯性的引用。

但是不使用空格虽然在技术上是可行的,但并不是真正的解决方案。

空格,无引号(损坏)

az webapp config set --name hello-shiny \
  --startup-file "Rscript -e 1 + 8"

正如预期的那样,仅[1] 1在 Azure 上产生,因为docker run会将之后的所有内容1视为单独的参数,因此忽略它。

空格,各种引用(全部损坏)

所以,没问题,有人可能会想,我会再逃避一些。

az webapp config set --name hello-shiny \
  --startup-file "Rscript -e '1 + 5'"
az webapp config set --name hello-shiny \
  --startup-file "Rscript -e \"1 + 6\""

这些,以及他们悲伤的朋友,都屈服了:

# Error: unexpected end of input
# Execution halted

这有点奇怪,因为这意味着R 代码的一部分(直到并包括+)使得它,虽然不是关键的5.

我能想到重现这一点的唯一方法是运行

docker run rstudio/r-base:4.0.2-xenial Rscript -e "1 +" 7
# Error: unexpected end of input
# Execution halted

这里发生了什么?

我绝对不能对 Azure 在这里所做的任何引用/转义做出正面或反面。我要么非常非常密集(可能),要么 Azure 做了一些非常奇怪和无证的事情(可能吗?)。

如何将带有空格的参数作为 a--startup-file传递给 Azure?

Ps.:我知道我可以通过CMD在 my 中添加相应的指令Dockerfile--startup-file留空来避免所有这些恶作剧,但是 a) 对于简单的选项来说这会很麻烦 b) 它必须是可能的

4

1 回答 1

0

没有官方文档解释该参数的--startup-file工作原理和限制。我只能给你我自己的意见。

首先,参数需要一个字符串值,你可以在这里得到关于属性的描述appCommandLine。这个时候,也许它只适用于不带引号的字符串。然后是图像的命令。你给命令Rscript参数-e 1+7。在 docker 命令中,您将它们放在引号中,例如"1 + 7",但是当引号消失时,它应该是1+7,没有空格。所以最后,参数的--startup-file值为"Rscript -e 1+7"

这只是我个人的看法,仅供参考。

于 2020-08-07T07:46:38.903 回答