首页 > 解决方案 > 如何避免来自 shell 中的内部 cat cmd 的反斜杠

问题描述

我正面临 shell 脚本的问题。我正在尝试读取可用的环境变量(由用户传递),如果存在,我想将它们附加到下面的 cmd 这个 cmd --> terraform plan 为了实现这一点,我正在读取所有已知的输入变量并准备一个看起来像这样的字符串 - ->'-var="db_ebs_volume_size=16" -var="db_dns_ttl=9999" ' 然后使用这个 cmd 将变量的包含回显到一个文件中 ->echo $temp > temp.txt 然后尝试执行这个整体 cmd,它会因以下错误而失败:

terraform plan $(cat temp.txt)

错误:-

│ Error: Value for undeclared variable
│
│ A variable named "\"db_dns_ttl" was assigned on the command line, but the
│ root module does not declare a variable of that name. To use this value,
│ add a "variable" block to the configuration.
╵
╷
│ Error: Value for undeclared variable
│
│ A variable named "\"db_ebs_volume_size" was assigned on the command line,
│ but the root module does not declare a variable of that name. To use this
│ value, add a "variable" block to the configuration.

我不知道为什么内部 cmd 的输出在双引号之前包含反斜杠 (),这会导致这里出现问题。如果我尝试运行这个 cmd,它工作正常:terraform plan -var="db_ebs_volume_size=16" -var="db_dns_ttl=9999"

我也尝试使用但仍然看到相同的错误"$(cat temp_cmd.txt |sed 's/\\\{1\}/\\\\/g' )"

任何人都可以帮助我如何在双引号之前避免这个反斜杠,以便它返回所需的字符串并且完整可以工作。

标签: bashshell

解决方案


简短的回答:不要将双引号存储在temp.txt

稍长的答案:将变量存储在.tfvars文件中并-var-file改用


解释:

引用用于允许 shell 解析输入:

$ a="1 2 3  4 5"
$ echo "[$a]"
[1 2 3  4 5]

$ b='"1 2  3 4 5"'
$ echo "[$b]"
["1 2  3 4 5"]

在上面的第一种情况下,双引号用于保护空格。

在第二种情况下,外部单引号保护空白,双引号被认为是值本身的一部分。

当您这样做$(cat temp.txt)时,shell 会将 cat 返回的所有内容视为值的一部分 - 包括双引号:

$ echo "a" > f
$ cat f
a
$ v=$(cat f)
$ echo "[$v]"
[a]

$ echo '"b"' > f
$ cat f
"b"
$ v=$(cat f)
$ echo "[$v]"
["b"]

当您直接运行命令时:

terraform plan -var="db_ebs_volume_size=16" -var="db_dns_ttl=9999"

shell 将该行解析为:

  • 程序:terraform
  • 论点1:plan
  • 论点2:-var=db_ebs_volume_size=16
  • 论点 3:-var=db_dns_ttl=9999

它调用terraform并传递三个参数。

terraform程序查看参数 2 时,它会将其解析为:

  • 命令:-var
  • 第一个=告诉它期待一个名称=值对
  • 姓名:db_ebs_volume_size
  • 第二个=表示名称的结尾/值的开始
  • 价值:16

当你运行时:

terraform plan $(cat temp.txt)

shell 首先获取 的值cat temp.txt,然后将其拆分为空格,并生成:

  • 程序:terraform
  • 论点1:plan
  • 论点2:-var="db_ebs_volume_size=16"
  • 论点 3:-var="db_dns_ttl=9999"

运行时terraform,它将参数 2 解析为:

  • 命令:-var
  • 第一个=告诉它期待一个名称=值对
  • 姓名:"db_ebs_volume_size
  • 第二个=表示名称的结尾/值的开始
  • 价值:16"

因此,要让您的代码正常工作,请不要存储双引号 - 它们不是必需的:

$ cat temp.txt
-var=db_ebs_volume_size=16 -var=db_dns_ttl=9999

更好的是,通过将变量存储在.tfvars文件中并加载来完全避开 shell 解析问题-var-file

$ cat my.tfvars
db_ebs_volume_size = 16
db_dns_ttl = 9999

$ terraform plan -var-file=my.tfvars

推荐阅读