# Ansible - Advanced shell command execution syntax

**URL:** <https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006>\
**Category:** Ansible Project\
**Created:** [August 22, 2014, 4:47am UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006 "2014-08-22T04:47:59Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Imran\_Khan1](https://avatars.discourse-cdn.com/v4/letter/i/a4c791/32.png) [@Imran\_Khan1](https://forum.ansible.com/u/Imran_Khan1)\
**Post date:** [August 22, 2014, 4:47am UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/1 "2014-08-22T04:47:59Z")

</div>

I have 3 variables named IPOctet, ServerIPRange and epcrange. If I perform the following operation in my terminal, it works perfectly

```auto
IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc)

```

How to I do something similar in a ansible inside a task, for e.g

```auto
---
- 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 Cleints that you want to configure
      private: False
      defualt: "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

```

What 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 sepearately?

---

<div class="post-metadata">

**Author:** ![Henry\_Finucane](https://avatars.discourse-cdn.com/v4/letter/h/94ad74/32.png) [@Henry\_Finucane](https://forum.ansible.com/u/Henry_Finucane)\
**Post date:** [August 22, 2014, 5:40am UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/2 "2014-08-22T05:40:27Z")

</div>

As an aside, you can do math in Jinja2-

- name: bashless math  
&nbsp;&nbsp;set\_fact:  
&nbsp;&nbsp;&nbsp;&nbsp;IPOctet: "{{ 4\*(ServerIPRange/epcrange)+IPOctet }}"

will do something approaching what you want.

If you want to get the actual shell-out working, something like this  
is going to be enlightening:

&nbsp;&nbsp;- name: local action math  
&nbsp;&nbsp;&nbsp;&nbsp;local\_action: shell echo "{{ServerIPRange}}/{{epcrange}}+{{IPOctet}}" | bc  
&nbsp;&nbsp;&nbsp;&nbsp;with\_sequence: start=1 end=4  
&nbsp;&nbsp;&nbsp;&nbsp;register: result  
&nbsp;&nbsp;- debug: var=result

"debug: var=result" will dump a pretty-printed JSON structure, so  
you'll know what's available, and what you can use. You should try it  
with & without the with\_sequence.

---

<div class="post-metadata">

**Author:** ![Imran\_Khan1](https://avatars.discourse-cdn.com/v4/letter/i/a4c791/32.png) [@Imran\_Khan1](https://forum.ansible.com/u/Imran_Khan1)\
**Post date:** [August 22, 2014, 6:17am UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/3 "2014-08-22T06:17:25Z")

</div>

Thank you for your quick reply:  
But this works, but not in a loop!

- name: bashless math  
set\_fact:  
IPOctet: “{{ (ServerIPRange|int/epcrange|int)+IPOctet|int }}”  
with\_sequence: start=1 end=4  
register: IPOctet

this wont work either:

- name: bashless math  
set\_fact:  
IPOctet: “{{ (ServerIPRange|int/epcrange|int)+IPOctet|int }}”  
register: IPOctet  
with\_sequence: start=1 end=4  
register: my\_ip\_octet

I need to save the value in IPOctet repetitively

---

<div class="post-metadata">

**Author:** ![Imran\_Khan1](https://avatars.discourse-cdn.com/v4/letter/i/a4c791/32.png) [@Imran\_Khan1](https://forum.ansible.com/u/Imran_Khan1)\
**Post date:** [August 22, 2014, 6:19am UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/4 "2014-08-22T06:19:21Z")

</div>

Again this will save the same value 4 times!

- name: local action math  
local\_action: shell echo “{{ServerIPRange}}/{{epcrange}}+{{IPOctet}}” | bc  
with\_sequence: start=1 end=4  
register: result
- debug: var=resu

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 22, 2014, 11:24am UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/5 "2014-08-22T11:24:13Z")

</div>

There’s a bugfix PR for that which I need to test.

You can of course still do this as a shell command too, right now.

What problem are you having at the shell?

---

<div class="post-metadata">

**Author:** ![Imran\_Khan1](https://avatars.discourse-cdn.com/v4/letter/i/a4c791/32.png) [@Imran\_Khan1](https://forum.ansible.com/u/Imran_Khan1)\
**Post date:** [August 22, 2014, 12:05pm UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/6 "2014-08-22T12:05:33Z")

</div>

The shell command only does the calculation once and stores the same value in each loop iteration. I want it to run the command by using the last calculated value, which is supposedly not happening for me. Can the jinj2 sum or replace filters be of any help ?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 22, 2014, 12:06pm UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/7 "2014-08-22T12:06:04Z")

</div>

I’m not understanding what “run the command using the last calculated value” means, unfortunately.

---

<div class="post-metadata">

**Author:** ![Imran\_Khan1](https://avatars.discourse-cdn.com/v4/letter/i/a4c791/32.png) [@Imran\_Khan1](https://forum.ansible.com/u/Imran_Khan1)\
**Post date:** [August 22, 2014, 12:44pm UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/8 "2014-08-22T12:44:10Z")

</div>

> Well I just want a loop, that does the following:

IPOctet=$(echo “$ServerIPRange/$epcrange+$IPOctet” | bc)

as you can see IPOctet is added to $ServerIPRange/$epcrange and the result is SAVED in IPOctet  
In each loop IPOctet is is say incremented by “x” and the result is saved in IPOctet again

What happens:  
The loop runs the number of times but saves the same value in each loop iteration.  
eg:  
IPOctet=“5”  
ServerIPRange=“16”  
epcrange=“2”  
IPOctet= 5 + 16/2 = 13

In the next iteration the result should be  
IPOctet= 13 + 8 = 21 //But what happens is that IPOctet stays constant at “13”

In the third iteration the result should be  
IPOctet= 21 + 8 = 29 //IPOctet is doesn’t change, reamins 13 and will remain 13 no matter how many iterations of the loop are run

I hope I have got my point across. Now any suggestions on the solution ?

---

<div class="post-metadata">

**Author:** ![Henry\_Finucane](https://avatars.discourse-cdn.com/v4/letter/h/94ad74/32.png) [@Henry\_Finucane](https://forum.ansible.com/u/Henry_Finucane)\
**Post date:** [August 22, 2014, 5:27pm UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/9 "2014-08-22T17:27:17Z")

</div>

> Thank you for your quick reply:  
> But this works, but not in a loop!
> 
> &nbsp;&nbsp;&nbsp;&nbsp;- name: bashless math  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPOctet: "{{ (ServerIPRange|int/epcrange|int)+IPOctet|int }}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_sequence: start=1 end=4  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register: IPOctet

You may have missed a crucial bit of what I wrote- your algorithm  
doesn't actually require any iteration. It decomposes into

IPrange/epcrange + (IPrange/epcrange + (IPrange/epcrange +  
(IPrange/epcrange + LastIPOctet) ) )

which is the same thing as

4 \* (IPrange/epcrange) + LastIPOctet

---

<div class="post-metadata">

**Author:** ![Imran\_Khan1](https://avatars.discourse-cdn.com/v4/letter/i/a4c791/32.png) [@Imran\_Khan1](https://forum.ansible.com/u/Imran_Khan1)\
**Post date:** [August 23, 2014, 5:09pm UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/10 "2014-08-23T17:09:26Z")

</div>

I posted that code piece of code for explanation purposes only, loop iteration i.e. the stop value is not fixed and will vary each time depending on user input (it is taken from the user at run time using vars\_prompt)

Please can you tell me how to do x=x+y with x=10(will change with each loop iteration) and y=5 (remains constant), inside a loop that runs ten any number of time

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [August 23, 2014, 7:32pm UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/11 "2014-08-23T19:32:43Z")

</div>

Isn’t what you are doing mathematically equivalent to:

z = x + (y \* iterations)

In which case, why do you need to store each result? Why not just run the task where you want to use this value using with\_sequence, and use this formula directly?

Such as this contrived example:

- debug: msg=“{{ IPOctet + (ServerIPRange//epcrange) \* item|int }}”  
with\_sequence: count=“{{ iterations }}”

---

<div class="post-metadata">

**Author:** ![Henry\_Finucane](https://avatars.discourse-cdn.com/v4/letter/h/94ad74/32.png) [@Henry\_Finucane](https://forum.ansible.com/u/Henry_Finucane)\
**Post date:** [August 23, 2014, 8:23pm UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/12 "2014-08-23T20:23:07Z")

</div>

> I posted that code piece of code for explanation purposes only, loop iteration i.e. the stop value is not fixed and will vary each time depending on user input (it is taken from the user at run time using vars\_prompt)
> 
> Please can you tell me how to do x=x+y with x=10(will change with each loop iteration) and y=5 (remains constant), inside a loop that runs ten any number of time

That decomposes the same way!

In any case, the yaml/jinja2 layer is generally the wrong layer to do logic in if your logic is going to get complicated. If you write a module, you can do anything python can do.

---

<div class="post-metadata">

**Author:** ![Imran\_Khan1](https://avatars.discourse-cdn.com/v4/letter/i/a4c791/32.png) [@Imran\_Khan1](https://forum.ansible.com/u/Imran_Khan1)\
**Post date:** [August 24, 2014, 8:52am UTC](https://forum.ansible.com/t/ansible-advanced-shell-command-execution-syntax/16006/13 "2014-08-24T08:52:16Z")

</div>

Nope, I can’t use them like that, my playbook is very complex, with some tasks running on some hosts serially
