Ansible
Ansible - 高级shell命令执行格式(Ansible - Advanced shell command execution format)我有3个变量名为IPOctet,ServerIPRange和epcrange。 如果我在我的终端中执行以下操作,它完美地工作
IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc)如何在任务内完成类似的事情,例如
---- hosts: localhost gather_facts: False vars_prompt: - name: epcrange prompt: Enter the number of EPCs that you want to configure private: False default: "1" - name: serverrange prompt: Enter the number of Clients that you want to configure private: False default: "1" - name: ServerIPRange prompt: Enter the ServerIP range private: False default: '128' - name: LastIPOctet prompt: Enter The last Octet of the IP you just entered private: False default: '10' pre_tasks: - name: Set some facts set_fact: ServerIP1: "{{ServerIP}}" ServerIPRange1: "{{ServerIPRange}}" IPOctet: "{{LastIPOctet}}" - name: local action math local_action: shell {{IPOctet}}=$(echo "${{ServerIPRange}}/${{epcrange}}+${{IPOctet}}" | bc) # Proper Syntax? with_sequence: start=1 end=4 register: result ignore_errors: yes这个命令的正确语法是什么? 也许使用shell回声“.......”。 我只需要将此命令的内容保存到IPOctet变量中,并且每次循环迭代时IPOctet都会更改,并且结果应该存储在我的结果寄存器中
PS:我如何分别访问阵列中的各个项目?
编辑:是否有这样的可能,目前它只做一次计算并将其存储在寄存器中4次...
- name: bashless math set_fact: IPOctet: "{{ (ServerIPRange|int/epcrange|int)+IPOctet|int }}" register: IPOctet with_sequence: "start=1 end={{stop}} " register: my_ip_octetI have 3 variables named IPOctet, ServerIPRange and epcrange. If I perform the following operation in my terminal, it works perfectly
IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc)How to I do something similar in a ansible inside a task, for e.g
---- hosts: localhost gather_facts: False vars_prompt: - name: epcrange prompt: Enter the number of EPCs that you want to configure private: False default: "1" - name: serverrange prompt: Enter the number of Clients that you want to configure private: False default: "1" - name: ServerIPRange prompt: Enter the ServerIP range private: False default: '128' - name: LastIPOctet prompt: Enter The last Octet of the IP you just entered private: False default: '10' pre_tasks: - name: Set some facts set_fact: ServerIP1: "{{ServerIP}}" ServerIPRange1: "{{ServerIPRange}}" IPOctet: "{{LastIPOctet}}" - name: local action math local_action: shell {{IPOctet}}=$(echo "${{ServerIPRange}}/${{epcrange}}+${{IPOctet}}" | bc) # Proper Syntax? with_sequence: start=1 end=4 register: result ignore_errors: yesWhat is the proper syntax for this command? Maybe using shell echo "......." . I just need to save the contents of this command into the IPOctet variable and IPOctet will change with each loop iteration and the results should be stored in my result register
P.S: how can I access the individual items in the array separately?
Edit: Is anything like this possible, currently it just does the calculation once and stores it 4 times in the register...
- name: bashless math set_fact: IPOctet: "{{ (ServerIPRange|int/epcrange|int)+IPOctet|int }}" register: IPOctet with_sequence: "start=1 end={{stop}} " register: my_ip_octet 最满意答案您的终端表达式将重新分配IPOctet shell变量,因此每次执行时都会给出不同的结果。 这很好,但很难在Ansible中重现:
$ IPOctet=10 ServerIPRange=128 epcrange=1$ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet138$ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet266语法: "shell {{IPOctet}}=$(echo ..."不会分配给Ansible变量。shell尝试执行一个像"10=138"这样的命令,该命令找不到。
当在循环中使用寄存器时,目标变量在循环完成之前不会被设置 - 所以您的表达式始终会看到{{IPOctet}}的原始值。
一个解决方案是将整个循环作为单个shell命令运行:
- name: local action math2 local_action: shell IPOctet={{IPOctet}}; for i in 1 2 3 4; do IPOctet=$(expr {{ServerIPRange}} / {{epcrange}} + $IPOctet); echo $IPOctet; done register: result注意:我使用expr命令而不是bc ,但结果相同。
您可以使用result.stdout_lines来遍历这些结果:
- name: iterate results local_action: debug msg={{item}} with_items: result.stdout_linesYour terminal expression reassigns the IPOctet shell variable, so it gives a different result each time it is executed. This is fine, but difficult to reproduce in Ansible:
$ IPOctet=10 ServerIPRange=128 epcrange=1$ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet138$ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet266The syntax: "shell {{IPOctet}}=$(echo ..." does NOT assign to the Ansible variable. The shell attempts to execute a command like "10=138", which is not found.
When register is used within a loop, the target variable is not set until the loop completes - so your expression always sees the original value for {{IPOctet}}.
A solution is to run the whole loop as a single shell command:
- name: local action math2 local_action: shell IPOctet={{IPOctet}}; for i in 1 2 3 4; do IPOctet=$(expr {{ServerIPRange}} / {{epcrange}} + $IPOctet); echo $IPOctet; done register: resultNOTE: I've used the expr command rather than bc, but the results are the same.
You can iterate over these results using result.stdout_lines:
- name: iterate results local_action: debug msg={{item}} with_items: result.stdout_lines