首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法找到寄存器结果result.stdout result.rc等dict变量,如何使用循环

无法找到寄存器结果result.stdout result.rc等dict变量,如何使用循环
EN

Stack Overflow用户
提问于 2016-12-28 04:05:54
回答 2查看 14.5K关注 0票数 3

ansible/ansible-剧本版本: 2.1.2.0 / 2.2.0.0

我试图使用yum/apt安装一个包,但是由于用于安装包的存储库位于packagecloud.io中,有时我会收到一条错误消息(当我在运行我的ansible-playbook时传递-vvv )。

代码语言:javascript
复制
[Errno 14] curl#56 - \"TCP connection reset by peer\"\nTrying other mirror. ...some ansible verbose text here.. [Errno 256] No more mirrors to try.

这种事并不总是发生的。如果我再次运行相同的剧本,它可以正常工作,所以失败(连接重置)是随机的。

为了克服这个问题,我想使用Ansible的until循环,这是我们必须与register变量一起使用的。

因此,我通过引用Ansible来创建这个剧本操作,以了解如何使用until循环这里,但是使用这种语法,我得到了一个“字典”错误,表示结果变量(已注册的) dict没有任何名为stdout的键。然后,我尝试使用result.rc (key字段),它在CentOS机器上工作,但在Ubuntu14.x可靠的迷途机器上失败,其中有以下result.rc dict未出现错误:

代码语言:javascript
复制
- name: Install telegraf agent/collector (RedHat)
  yum:
    name: "{{ agent_collector }}"
    state: "installed"
  when: ( ansible_os_family == 'RedHat' and company_install_collector == true )
  register: result
  until: result.stdout.find("Installed:") != -1
  #The following works in CentOS/RedHat
  #until: result.rc == 0  

 - debug: msg="result (redhat) = {{ result }}"

或者(更新我的问题,这是显而易见的)

代码语言:javascript
复制
- name: Install Company Proxy (Ubuntu)
  apt:
    name: "{{ company_proxy_pkg }}"
    state: "installed"
  when: ( ansible_distribution == 'Ubuntu' and company_install_proxy == true )
  register: result
  until: result.rc == 0

 - debug: msg="result (ubuntu) = {{ result }}"

获取以下错误消息(在RedHat/CentOS和Ubuntu中,result.stdout对象‘没有属性'stdout’,但是在Ubuntu中,获取dict对象没有属性'rc‘):

代码语言:javascript
复制
fatal: [localhost]: FAILED! => {"failed": true, "msg": "The conditional check '(result.stdout.find(\"Installed:\") != -1)' failed. The error was: error while evaluating conditional ((result.stdout.find(\"Installed:\") != -1)): 'dict object' has no attribute 'stdout'"}

代码语言:javascript
复制
fatal: [localhost]: FAILED! => {
    "failed": true, 
    "msg": "The conditional check 'result.rc == 0' failed. The error was: error while evaluating conditional (result.rc == 0): 'dict object' has no attribute 'rc'"
}

为什么寄存器变量(在我的例子中是结果)不具有stdoutrc dict/变量,因为文档表明这些变量是存在的,或者如果我可以在一个操作系统上的-vvv上看到这些变量,但在另一个操作系统上却没有显示它们?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-28 05:58:54

正确的答案和发现:

  1. In CentOS,如果操作成功,并且设置了注册变量结果,则用户可以看到ex的这些dict变量: result.rc为0,result.stdout =“nsomethingEsle\netc等”和/或result.stdout_lines = "...same如上.“。和result.results在某些情况下。如果操作失败,则如果由于result.stdout或其他原因导致yum模块失败,则无法在我的示例中设置该操作。在这种情况下,失败操作唯一可用的dict变量是result.rc != 0。因此,在until循环中,until: result.rc == 0条件对CentOS成功/失败的情况都有效。
  2. 在Ubuntu中,如果apt模块操作成功,我获得了result.stdout和result.stdout_lines变量集,但没有result.rc dict变量集。对于失败的操作,没有设置result.stdout、result.stdout_lines或result.rc dict变量。因此,对于Ubuntu,我不能使用这些字典变量中的一个使用until循环。

我能想到的唯一解决办法是,将apt-get install <pacakge>封装在脚本中,并使用BASH等中的循环来完成Ansible正在做的事情。至少,编写代码要容易得多,如果退出代码不是0,那么我可以使用until

但是,我终于找到了一个解决方案,它在Ubuntu中对成功和失败的案例都有效:

因此,Jinja2过滤器可以帮助when: result|failed,因此,如果我必须为失败的条件使用一个注册变量result,然后使用until,我将使用它(与失败状态相反),即:

代码语言:javascript
复制
until: result|succeeded

好的是,上面的“直到”语句将同时适用于CentOS和Ubuntu以及两个成功/失败的状态。

票数 3
EN

Stack Overflow用户

发布于 2019-04-21 06:03:04

不推荐使用测试作为筛选器。不要使用result|succeeded,而是使用result is succeeded。此功能将在2.9版中删除。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41355185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档