执行 Ansible 中的命令并从中减去一个数字。

huangapple go评论62阅读模式
英文:

how to execute cmd in ansible and subtract a number to it

问题

我正在尝试使用 nproc 获取核心数,然后减去 2 并将其赋值给一个变量。

我尝试了这样的方式:

- set_fact:
    num_cores: nproc

- debug:
    msg: " {{ num_cores }}"
  when: num_cores is defined

- set_fact:
    update: "{{ num_cores-2 }}"

调试打印出了 nproc,这告诉我它没有执行 nproc 命令,而只是将字符串赋值给变量。
我漏掉了什么?

英文:

I am trying to retrieve the number of cores using nproc and then subtract 2 from it and assign it to a variable.

I tried this

- set_fact:
    num_cores: nproc

- debug:
    msg: " {{ num_cores }}"
  when: num_cores is defined

- set_fact:
    update: "{{ num_cores-2 }}"

The debug prints nproc which tells me it is not executing the cmd nproc but just assigning the string to the variable.
What am I missing?

答案1

得分: 2

以下是翻译的内容:

当你编写:

- set_fact:
    some_variable: some_value

你正在创建一个变量(在本例中为some_variable),其值为字符串(some_value)。Ansible 不知道你实际上想要执行一个命令。

如果你想要将命令的输出存储到一个变量中,请使用command模块和register选项来将输出存储到一个变量中:

- name: 获取 nproc
  command: nproc
  register: num_cores

这会创建一个看起来像这样的变量num_cores

"num_cores": {
    "changed": true,
    "cmd": [
        "nproc"
    ],
    "delta": "0:00:00.001626",
    "end": "2023-06-11 23:28:40.015719",
    "failed": false,
    "msg": "",
    "rc": 0,
    "start": "2023-06-11 23:28:40.014093",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "20",
    "stdout_lines": [
        "20"
    ]
}

所以在这个示例中你想要的值是num_cores.stdout。重新编写你的示例,看起来会像这样:

- hosts: localhost
  tasks:
    - name: 获取 nproc
      command: nproc
      register: num_cores

    - debug:
        msg: "{{ num_cores }}"
      when: num_cores is defined

    # num_cores.stdout 包含我们想要的值,但它是一个字符串,所以如果我们要在数学表达式中使用它,我们需要首先将其转换为整数。
    - set_fact:
        update: "{{ num_cores.stdout|int - 2 }}"

    - debug:
        msg: "{{ update }}"

这将产生以下结果:

TASK [Get nproc] ****************************************************************************************
changed: [localhost]

TASK [debug] ********************************************************************************************
ok: [localhost] => {
    "msg": {
        "changed": true,
        "cmd": [
            "nproc"
        ],
        "delta": "0:00:00.001601",
        "end": "2023-06-11 23:31:02.646133",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2023-06-11 23:31:02.644532",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "20",
        "stdout_lines": [
            "20"
        ]
    }
}

TASK [set_fact] *****************************************************************************************
ok: [localhost]

TASK [debug] ********************************************************************************************
ok: [localhost] => {
    "msg": "18"
}

请注意,Ansible 已经在变量ansible_processor_nproc中提供了nproc的值(假设你启用了事实收集,这是默认行为),所以你可以将你的playbook 简化为:

- hosts: localhost
  tasks:
    - set_fact:
        update: "{{ ansible_processor_nproc - 2 }}"
        
    - debug:
        msg: "{{ update }}"
英文:

When you write:

- set_fact:
    some_variable: some_value

You are creating a variable (in this case some_variable) with a string value (some_value). Ansible doesn't know that you actually meant to execute a command.

If you want to store the output of a command in a variable, use the command module and the register option to store the output in a variable:

- name: Get nproc
  command: nproc
  register: num_cores

This creates a variable num_cores that looks like:

"num_cores": {
    "changed": true,
    "cmd": [
        "nproc"
    ],
    "delta": "0:00:00.001626",
    "end": "2023-06-11 23:28:40.015719",
    "failed": false,
    "msg": "",
    "rc": 0,
    "start": "2023-06-11 23:28:40.014093",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "20",
    "stdout_lines": [
        "20"
    ]
}

So the value you want in this example is num_cores.stdout. Rewriting your example, that would look like:

- hosts: localhost
  tasks:
    - name: Get nproc
      command: nproc
      register: num_cores

    - debug:
        msg: "{{ num_cores }}"
      when: num_cores is defined

    # num_cores.stdout has the value we want, but it's
    # a string, so if we're going to use it in a math
    # expression we need to convert it to an int first.
    - set_fact:
        update: "{{ num_cores.stdout|int - 2 }}"

    - debug:
        msg: "{{ update }}"

Which produces:

TASK [Get nproc] ****************************************************************************************
changed: [localhost]

TASK [debug] ********************************************************************************************
ok: [localhost] => {
    "msg": {
        "changed": true,
        "cmd": [
            "nproc"
        ],
        "delta": "0:00:00.001601",
        "end": "2023-06-11 23:31:02.646133",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2023-06-11 23:31:02.644532",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "20",
        "stdout_lines": [
            "20"
        ]
    }
}

TASK [set_fact] *****************************************************************************************
ok: [localhost]

TASK [debug] ********************************************************************************************
ok: [localhost] => {
    "msg": "18"
}

Note that Ansible already provides the value of nproc in the variable ansible_processor_nproc (assuming that you have fact gathering enabled, which is the default behavior), so you could reduce your playbook to:

- hosts: localhost
  tasks:
    - set_fact:
        update: "{{ ansible_processor_nproc - 2 }}"

    - debug:
        msg: "{{ update }}"

huangapple
  • 本文由 发表于 2023年6月12日 10:39:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76453348.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定