Ansible - Advanced shell command execution format
Your 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 $IPOctet266
The 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: result
NOTE: I've used the
expr
command rather thanbc
, 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
Firstly your Jinja template is incorrect, every single variable needs to be surrounded with a pair of brackets. You can not use multiple variables within single pair of brackets. For example,
{{ ServerIPRange }}
Secondly, set_fact is used only to set a fact value. You can not run shell commands using set_fact. You should use shell module instead.
- name: local action math local_action: shell {{ IPOctet }}=$(echo {{ ServerIPRange|int }}/{{ epcrange|int }}+{{ IPOctet|int }}" | bc) with_sequence: start=1 end=4 register: result ignore_errors: yes
Ansible will do the calculation 4 times and store it in a list as 4 different elements. You can check what all is stored inside this list and can even access it by looping over it.
- debug: msg={{ result }}
Hope this helps :)