如何使用 set_fact 和 with_together?
How can I use set_fact and with_together?
我正在尝试转换 bash 源自远程计算机上的属性文件的环境变量。我正在将键和值注册到两个寄存器变量,然后尝试使用 with_together
和 set_fact
循环遍历它们
这是我获取变量的方式key/values
- name: Source Env Properties
shell: . <source utility> && ( set -a posix ; set| sed 's,=.*,,' )
register: variable_keys
- shell: . <source utility> && ( set -a posix ; set| sed 's,^.*=,,' )
register: variable_values
之后我尝试set_fact
使用两个注册值。
- name: set variables
set_fact:
"{{item.0}}:{{item.1}}"
with_together:
- "{{ variable_keys.stdout_lines }}"
- "{{ variable_values.stdout_lines }}"
任务的输出看起来应该可以工作,但是当尝试使用这些变量时,它说它们没有定义。
谁能告诉我为什么这不起作用?
因此,正如我在评论中提到的,您的第一个问题是 set_fact
块中的语法不正确。如果你有这个:
"{{item.0}}:{{item.1}}"
那么你只有一个字符串,而不是 key: value
对。您需要将其修改为
- name: set variables
set_fact:
"{{item.0}}": "{{item.1}}"
with_together:
- "{{ variable_keys.stdout_lines }}"
- "{{ variable_values.stdout_lines }}"
但这只是问题的一半。您的 sed
表达式最终可能会产生语法上无效的输出,因为它们将包含 bash 函数定义。也就是说,如果我 运行 我本地环境中的第一个命令,输出包括来自 shell 函数的所有内容,用于 bash 完成、git 提示等,像这样:
scl ()
{
local CMD
if [ "$CMD"
eval "module $@";
else
/usr/bin/scl "$@";
fi
}
这将破坏 ansible:
failed: [localhost] (item=[u"'", u"'"]) => {"changed": false, "failed": true, "item": ["'", "'"], "msg": "The variable name ''' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores."}
您需要确保过滤掉该内容。我用过这个:
- name: Source Env Properties
shell: . ./myvars.sh && ( set -a posix; set| sed -n '/^[A-Z]/ s,=.*,,p' )
register: variable_keys
- shell: . ./myvars.sh && ( set -a posix; set| sed -n '/^[A-Z]/ s,^.*=,,p' )
register: variable_values
- name: set variables
set_fact:
"{{item.0}}": "{{item.1}}"
with_together:
- "{{ variable_keys.stdout_lines }}"
- "{{ variable_values.stdout_lines }}"
如果我有,在myvars.sh
:
FOO=bar
如果在我的剧本中有,在上面之后:
- debug:
var: FOO
我将看到输出:
ok: [localhost] => {
"FOO": "bar"
}
顺便说一句,我认为 sed
的所有这些乱七八糟的事情很脆弱,可能会在未来引起其他问题。我可能会这样做:
- name: Source Env Properties
shell: |
set -a
. ./myvars.sh
jq -n env
register: vars_raw
- set_fact:
shellvars: "{{ vars_raw.stdout|from_json }}"
- debug:
var: shellvars.FOO
这里使用jq
将所有可用的环境变量导出为JSON,然后将结果赋值给shellvars
变量。 set -a
确保 myvars.sh
中设置的任何变量都导出到环境中。如果手边没有 jq
,可以使用 python
:
- name: Source Env Properties
shell: |
set -a
. ./myvars.sh
python -c 'import json; import os; print(json.dumps(dict(os.environ)))'
register: vars_raw
- set_fact:
shellvars: "{{ vars_raw.stdout|from_json }}"
- debug:
var: shellvars.FOO
我正在尝试转换 bash 源自远程计算机上的属性文件的环境变量。我正在将键和值注册到两个寄存器变量,然后尝试使用 with_together
和 set_fact
这是我获取变量的方式key/values
- name: Source Env Properties
shell: . <source utility> && ( set -a posix ; set| sed 's,=.*,,' )
register: variable_keys
- shell: . <source utility> && ( set -a posix ; set| sed 's,^.*=,,' )
register: variable_values
之后我尝试set_fact
使用两个注册值。
- name: set variables
set_fact:
"{{item.0}}:{{item.1}}"
with_together:
- "{{ variable_keys.stdout_lines }}"
- "{{ variable_values.stdout_lines }}"
任务的输出看起来应该可以工作,但是当尝试使用这些变量时,它说它们没有定义。
谁能告诉我为什么这不起作用?
因此,正如我在评论中提到的,您的第一个问题是 set_fact
块中的语法不正确。如果你有这个:
"{{item.0}}:{{item.1}}"
那么你只有一个字符串,而不是 key: value
对。您需要将其修改为
- name: set variables
set_fact:
"{{item.0}}": "{{item.1}}"
with_together:
- "{{ variable_keys.stdout_lines }}"
- "{{ variable_values.stdout_lines }}"
但这只是问题的一半。您的 sed
表达式最终可能会产生语法上无效的输出,因为它们将包含 bash 函数定义。也就是说,如果我 运行 我本地环境中的第一个命令,输出包括来自 shell 函数的所有内容,用于 bash 完成、git 提示等,像这样:
scl ()
{
local CMD
if [ "$CMD"
eval "module $@";
else
/usr/bin/scl "$@";
fi
}
这将破坏 ansible:
failed: [localhost] (item=[u"'", u"'"]) => {"changed": false, "failed": true, "item": ["'", "'"], "msg": "The variable name ''' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores."}
您需要确保过滤掉该内容。我用过这个:
- name: Source Env Properties
shell: . ./myvars.sh && ( set -a posix; set| sed -n '/^[A-Z]/ s,=.*,,p' )
register: variable_keys
- shell: . ./myvars.sh && ( set -a posix; set| sed -n '/^[A-Z]/ s,^.*=,,p' )
register: variable_values
- name: set variables
set_fact:
"{{item.0}}": "{{item.1}}"
with_together:
- "{{ variable_keys.stdout_lines }}"
- "{{ variable_values.stdout_lines }}"
如果我有,在myvars.sh
:
FOO=bar
如果在我的剧本中有,在上面之后:
- debug:
var: FOO
我将看到输出:
ok: [localhost] => {
"FOO": "bar"
}
顺便说一句,我认为 sed
的所有这些乱七八糟的事情很脆弱,可能会在未来引起其他问题。我可能会这样做:
- name: Source Env Properties
shell: |
set -a
. ./myvars.sh
jq -n env
register: vars_raw
- set_fact:
shellvars: "{{ vars_raw.stdout|from_json }}"
- debug:
var: shellvars.FOO
这里使用jq
将所有可用的环境变量导出为JSON,然后将结果赋值给shellvars
变量。 set -a
确保 myvars.sh
中设置的任何变量都导出到环境中。如果手边没有 jq
,可以使用 python
:
- name: Source Env Properties
shell: |
set -a
. ./myvars.sh
python -c 'import json; import os; print(json.dumps(dict(os.environ)))'
register: vars_raw
- set_fact:
shellvars: "{{ vars_raw.stdout|from_json }}"
- debug:
var: shellvars.FOO