我正在尝试从 bash 脚本运行此命令并从 bash 参数中传递额外的变量。
#!/bin/bash
ansible-playbook /path/to/playbook.yml --extra-vars "var1=1 $@" > /path/to/log/file
我像下面这样运行脚本并收到此错误:
> ./test.bs var2=2 var3=3
ERROR! the playbook: var3=3 could not be found
我什至尝试转义引号,但没有用。如何让它运行?
,您可以将脚本更改为使用 $*:
#!/bin/bash
ansible-playbook /path/to/playbook.yml --extra-vars "var1=1 $*" > /path/to/log/file
只要您使用的是 Ansible 1.2 或更高版本,最健壮的做法就是使用 jq
生成 JSON。以下内容将对任意数量的键=值参数执行此操作:
#!/bin/bash
jq_args=( )
jq_text='{}'
i=0
for arg in var1=1 "$@"; do
[[ $arg = *=* ]] || continue # require arguments to be in key=value form
key=${arg%%=*}
value=${arg#*=}
jq_args+=( --arg "key$i" "$key" --arg "value$i" "$value" )
jq_text+=" | .[$key$i]=$value$i"
((i++))
done
json_final=$(jq "${jq_args[@]}" "$jq_text" <<<"$json") # || exit
ansible-playbook /path/to/playbook.yml --extra-vars "$json_final"
您正在向--extra-vars
传递一个长参数,因为它都在相同的"
标记内。 您正在构建单个var1=1 arg1 arg2 arg3
字符串。
您的意图可能是传递三个参数,每个参数都是看起来像var1=1
var2=2
var3=3
的字符串
话虽如此,请尝试此。
ansible-playbook /path/to/playbook.yml --extra-vars "var1=1" "$@" > /path/to/log/file
这样,您将第一个 arg 作为字符串传递"var1=1"
然后 bash "$@"
扩展为您传递给程序的各个参数。
因此,使用上面的代码片段./test.bs var2=2 var3=3
将正确执行。 为了理智起见,尽管最好将您的参数包装在"
尽管在这种情况下没有必要。 养成这个习惯是件好事,因为有一天你会跑./test.bs var2=*
并获得一些疯狂的输出。 所以最后,最理智的电话将是...
./test.bs "var2=2" "var3=3"
像这样运行它:
> ./test.bs 'var2=2 var3=3'
似乎是正确的,应该有效。
引用和不引用var1=1 $@
只会对参数的传递方式产生影响。不引用它将允许引用参数(即 "var2=2 var3=3"
( 或未引用(即 var2=2 var3=3
(,因为它会将空间分隔的参数扩展为单独的参数。如果引用$@
,则必须传递参数而不是引用或单独引用(即 "var2=2" "var3=3"
(,因此它们被接受为单独的论点。
一种肯定可行的选项是使用 eval
,但是,通常避免这样做,因为它允许传递不安全的数据。基本上只是把eval
放在命令之前:
eval ansible-playbook /path/to/playbook.yml --extra-vars "var1=1 $@"
> /path/to/log/file
它将通过命令,解析它并删除所有一级引号,使命令ansib ... --extra-vars var1=1 var2=2 var3=3 > /path...
。