简体   繁体   English

"无法在 Terraform 中运行 shell 脚本"

[英]Unable to run shell script in Terraform

I am trying to run a shell script with the local-exec command in Terraform.我正在尝试使用 Terraform 中的 local-exec 命令运行 shell 脚本。 When I run this, it keeps coming up with the error "Can't open appsettings.sh"<\/code> .当我运行它时,它不断出现错误"Can't open appsettings.sh"<\/code> 。 This script runs fine when run manually.此脚本在手动运行时运行良好。 Any ideas what I am missing?有什么我想念的想法吗?

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}"
  }
}

The error message is stating that it "Can't open" the script file. 错误消息指出它“无法打开”脚本文件。 The reason might be: 原因可能是:

  1. The script file is not present (may be it is not yet created on machine) 脚本文件不存在(可能尚未在计算机上创建)
  2. Permission issue 权限问题

If you are running command through a program (eg terraform or script) you need to specify the shell and or proper path. 如果您正在通过程序(例如terraform或脚本)运行命令,则需要指定shell和/或正确的路径。 Example: 例:

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

I am not sure but I think local-exec is used to run the local commands like ls, echo, mkdir etc and remote-exec is used to run the script. 我不确定,但是我认为local-exec用于运行ls,echo,mkdir等本地命令,而remote-exec用于运行脚本。 Though I have not yet used this provisioner but you can play around this. 尽管我尚未使用此资源provisioner但是您可以尝试一下。

Refrances: https://www.terraform.io/docs/provisioners/local-exec.html 弗朗西斯: https ://www.terraform.io/docs/provisioners/local-exec.html

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

The issue here is, terraform run the command as 这里的问题是,terraform将命令运行为

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

So the command interpreter take appsettings.sh as the command name which is very similar to running as below 因此,命令解释器将appsettings.sh作为命令名称,与按以下方式运行非常相似

$appsettings.sh arg1 arg2

which cannot be done as there is no command like this. 这是无法完成的,因为没有这样的命令。 So to run that shell script you either has to provide the absolute path of the shell script or relative as shown below 因此,要运行该外壳脚本,您必须提供外壳脚本的绝对路径或相对路径,如下所示

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

To achieve this rearrange your command attr as below 要实现此目的,请按以下方式重新排列命令属性

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}"

ie add ./appsettings 即添加./appsettings

OK I get it now.好的,我现在明白了。

TLDR version TLDR 版本<\/h1>

Remove interpreter ( interpreter = ["sh"]<\/code> ) at all or add -c<\/code> as another parameter, like this: interpreter = ["sh", "-c"]<\/code> or even better interpreter = ["\/bin\/sh", "-c"]<\/code> .完全删除解释器( interpreter = ["sh"]<\/code> )或添加-c<\/code>作为另一个参数,如下所示: interpreter = ["sh", "-c"]<\/code>甚至更好的interpreter = ["\/bin\/sh", "-c"]<\/code> 。 Additionally you need to provide path to script so add .\/<\/code> or ${path.module}\/<\/code> .此外,您需要提供脚本路径,因此添加.\/<\/code>或${path.module}\/<\/code> 。

NOTE: also as far as I see script needs to be executable ( chmod +x appsettings.sh<\/code> ).注意:据我所知,脚本需要是可执行的( chmod +x appsettings.sh<\/code> )。

<\/blockquote>

Full version完整版本<\/h1>

The problem is with default interpretation of local-exec<\/code> .问题在于local-exec<\/code>的默认解释。 If you do not set interpreter then the default one is \/bin\/sh -c<\/code> (Linux) and if you add command\/script with parameters\/arguments it looks like this如果你没有设置解释器,那么默认的是\/bin\/sh -c<\/code> (Linux),如果你添加带有参数\/参数的命令\/脚本,它看起来像这样

["\/bin\/sh", "-c", ".\/appsettings.sh ab"]<\/code><\/pre>

but what you were trying to do is to run something like this但你想做的是运行这样的东西

["\/bin\/sh", ".\/appsettings.sh ab"]<\/code><\/pre>

If we test both this approaches in terminal then we will see:如果我们在终端测试这两种方法,那么我们将看到:

 $ \/bin\/sh -c ".\/appsettings.sh ab" Params: ab $ \/bin\/sh ".\/appsettings.sh ab" \/bin\/sh: 0: Can't open .\/appsettings.sh ab<\/code><\/pre>

In \/bin\/sh<\/code> and \/bin\/bash<\/code> shells -c<\/code> parameters is responsible for:\/bin\/sh<\/code>和\/bin\/bash<\/code> shells 中-c<\/code>参数负责:

Read commands from the command_string operand instead of from the standard input.<\/em>从 command_string 操作数而不是从标准输入读取命令。<\/em>

<\/blockquote>

NOTE: if you want to read more check this out:https:\/\/askubuntu.com\/questions\/831847\/what-is-the-sh-c-command<\/a><\/em>注意:如果您想阅读更多内容,请查看:https<\/a> :\/\/askubuntu.com\/questions\/831847\/what-is-the-sh-c-command<\/em>

<\/blockquote>

Final corrected script should looks like this:最终更正的脚本应如下所示:

 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}" } }<\/code><\/pre>

If you would like to use bash<\/code> instead of sh<\/code> then it should be like this:如果您想使用bash<\/code>而不是sh<\/code>那么它应该是这样的:

 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"] } }```<\/code><\/pre>"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM