Bash Ansible-高级shell命令执行格式

Bash Ansible-高级shell命令执行格式,bash,shell,loops,ansible,ansible-playbook,Bash,Shell,Loops,Ansible,Ansible Playbook,我有三个变量,分别是ipocet、ServerIPRange和epcrange。 如果我在终端中执行以下操作,它将正常工作 IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc) 如何在任务内部的ansible中执行类似的操作,例如 --- - hosts: localhost gather_facts: False vars_prompt: - name: epcrange prompt: Enter t

我有三个变量,分别是ipocet、ServerIPRange和epcrange。 如果我在终端中执行以下操作,它将正常工作

IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc)
如何在任务内部的ansible中执行类似的操作,例如

---
- 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 echo“…”。我只需要将这个命令的内容保存到IPOctet变量中,IPOctet将随着每次循环迭代而改变,结果应该存储在我的结果寄存器中

附言:我怎样才能单独访问阵列中的各个项目

编辑:这样做是可能的,目前它只做一次计算,并将其存储在寄存器中4次

- name: bashless math
  set_fact:
    IPOctet: "{{ (ServerIPRange|int/epcrange|int)+IPOctet|int }}"
  register: IPOctet
  with_sequence: "start=1 end={{stop}} "
  register: my_ip_octet

首先,您的Jinja模板不正确,每个变量都需要用一对括号括起来。不能在一对括号内使用多个变量。比如说,

{{ ServerIPRange }}
其次,set_fact仅用于设置事实值。不能使用set_fact运行shell命令。您应该改用shell模块

- 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将进行4次计算,并将其作为4个不同的元素存储在列表中。您可以检查此列表中存储的所有内容,甚至可以通过循环访问它

- debug: msg={{ result }}
希望这有帮助:)

  • 您的终端表达式重新分配IPOctet shell变量,因此每次执行时都会给出不同的结果。这很好,但很难在Ansible中复制:

    $ IPOctet=10 ServerIPRange=128 epcrange=1
    $ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet
    138
    
    $ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet
    266
    
  • 语法:
    “shell{{IPOctet}}=$(echo…”
    未分配给Ansible变量。 shell尝试执行类似于
    “10=138”
    的命令,但未找到该命令

  • 当在循环中使用register时,直到循环完成才设置目标变量-因此表达式总是看到
    {{ipocet}
    的原始值

  • 解决方案是将整个循环作为单个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\u行迭代这些结果:

    - name: iterate results
      local_action: debug msg={{item}}
      with_items: result.stdout_lines
    

  • 多谢了。还有一件事,这个循环是硬编码的,我可以这样做吗:for(inti=0,我可以在范围(0,{IPOctet},{{2**{x}}}}}}})中为I创建一个这样的循环,其中x是vars_提示符中某个地方定义的变量。是的,可以使用bash算法进行循环(注意双参数):for((i=0;i)