【问题标题】:Unable to run shell script in Terraform无法在 Terraform 中运行 shell 脚本
【发布时间】:2020-01-01 18:04:35
【问题描述】:

我正在尝试在 Terraform 中使用 local-exec 命令运行 shell 脚本。当我运行它时,它不断出现错误"Can't open appsettings.sh"。此脚本在手动运行时运行良好。有什么我想念的想法吗?

resource "null_resource" "sp" {

  triggers = {
    shell_hash = "${sha256(file("${path.module}/appsettings.sh"))}"
  }
  provisioner "local-exec" {
      command = "appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
      interpreter = ["sh"]
      working_dir = "${path.module}"
  }
}

错误信息:

Error: Error running command 'appsettings.sh 59942507-xxxx-xxxx-xxxxx 4c64-xxxx-xxxx-xxxxx': exit status 127. Output: sh: 0: Can't open appsettings.sh 59942507-xxxx-xxxx-xxxxx 4c64-xxxx-xxxx-xxxxx'

【问题讨论】:

  • 不是权限问题??
  • 我不这么认为,这只是在我的本地台式机上运行,​​所有文件都是本地的
  • 今天上班碰巧有一个类似的案例,用ide和终端得到的结果不一样,确实是权限不一样的问题,我用你的代码状态在网上搜索了这个理由,没有成功, 但我得到的唯一结果是你的文件可能需要从 Linux 转换为 Linux .. https://github.com/hashicorp/terraform/issues/5821
  • 它看起来像是命令,如果我在提示符下运行相同的 sh 命令,则会收到此错误。如果我调整引号,我可以让它在本地运行,但在 Terraform 中还没有运气

标签: bash azure shell terraform


【解决方案1】:

这里的问题是,terraform 将命令运行为

["/bin/sh" "-c" "appsettings.sh arg1 arg2"]

所以命令解释器把appsettings.sh作为命令名,和下面的运行非常相似

$appsettings.sh arg1 arg2

因为没有这样的命令,所以无法做到。因此,要运行该 shell 脚本,您必须提供 shell 脚本的绝对路径或相对路径,如下所示

$ ./appsettings.h
$ /home/user/appsettings.sh # Example

要实现这一点,请重新排列您的命令属性,如下所示

command = "./appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"

 OR

command = "${path.module}/appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"

即添加 ./appsettings

【讨论】:

    【解决方案2】:

    错误消息表明它“无法打开”脚本文件。 原因可能是:

    1. 脚本文件不存在(可能尚未在机器上创建)
    2. 权限问题

    如果您通过程序(例如 terraform 或脚本)运行命令,则需要指定 shell 和/或正确的路径。 示例:

    /bin/sh /path/to/script/myscript.sh
    or
    /bin/bash /path/to/script/myscript.sh
    

    我不确定,但我认为local-exec 用于运行本地命令,如 ls、echo、mkdir 等,remote-exec 用于运行脚本。 虽然我还没有使用过这个provisioner,但你可以玩这个。

    参考文献: https://www.terraform.io/docs/provisioners/local-exec.html

    https://www.terraform.io/docs/provisioners/remote-exec.html

    【讨论】:

      【解决方案3】:

      好的,我现在明白了。

      TLDR 版本

      完全删除解释器 (interpreter = ["sh"]) 或添加 -c 作为另一个参数,如下所示:interpreter = ["sh", "-c"] 甚至更好的 interpreter = ["/bin/sh", "-c"]。此外,您需要提供脚本路径,因此请添加 ./${path.module}/

      注意:据我所知,脚本需要是可执行的 (chmod +x appsettings.sh)。

      完整版

      问题在于local-exec 的默认解释。如果你没有设置解释器,那么默认的是/bin/sh -c(Linux),如果你添加带有参数/参数的命令/脚本,它看起来像这样

      ["/bin/sh", "-c", "./appsettings.sh a b"]
      

      但你试图做的是运行这样的事情

      ["/bin/sh", "./appsettings.sh a b"]
      

      如果我们在终端中测试这两种方法,我们将看到:

      $ /bin/sh -c "./appsettings.sh a b"
      Params: a b
      $ /bin/sh "./appsettings.sh a b"
      /bin/sh: 0: Can't open ./appsettings.sh a b
      

      /bin/sh/bin/bash shells中-c参数负责:

      从 command_string 操作数而不是从标准输入读取命令。

      注意:如果您想了解更多信息,请查看:https://askubuntu.com/questions/831847/what-is-the-sh-c-command

      最终更正后的脚本应如下所示:

      resource "null_resource" "sp" {
      
        triggers = {
          shell_hash = "${sha256(file("${path.module}/appsettings.sh"))}"
        }
        provisioner "local-exec" {
          command = "./appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
        }
      }
      

      如果你想使用bash 而不是sh 那么它应该是这样的:

      resource "null_resource" "sp" {
      
        triggers = {
          shell_hash = "${sha256(file("${path.module}/appsettings.sh"))}"
        }
        provisioner "local-exec" {
          command = "./appsettings.sh ${azuread_application.rbac-server-principal.application_id} ${azuread_application.rbac-client-principal.application_id}"
          interpreter = ["/bin/bash", "-c"]
        }
      }```
      
      

      【讨论】:

        猜你喜欢
        • 2017-09-09
        • 2019-02-17
        • 2023-03-14
        • 1970-01-01
        • 2023-03-04
        • 2016-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多