ansible.builtin.command

command 是用來執行指令用的。

例如

- name: Return motd to registered var
  command: cat /etc/motd
  register: mymotd

這行就是執行 cat /etc/motd,然後把執行結果放到 mymotd 變數裡。

那如果要在指定的目錄下執行命令呢?我們可以使用 chdir

- name: 切到 /tmp 目錄下,然後以 db_owner 使用者身分來建立空檔案。
  command: touch db.sqlite3
  become: yes
  become_user: db_owner
  args:
    chdir: /tmp

有些指令會需要很多參數,擺在一行裡會不容易閱讀,command 可以用 argv 來替代,提高可讀性。 以上面的例子來說,可以改寫為

- name: 切到 /tmp 目錄下,然後以 db_owner 使用者身分來建立空檔案。
  command:
    argv:
      - touch
      - db.sqlite3
  become: yes
  become_user: db_owner
  args:
    chdir: /tmp

command 的 creates 則是可以依據檔案是否存在來決定是否要執行指令。 這有一個先決要件,就是你需要知道指令會產生該檔案。

首先,先產生一個叫做 test-command-creates.sh 的指令檔

#!/bin/bash
echo "$(date)" >> /tmp/test-command-creates.txt

從這指令檔可以看出,他會在 /tmp 下產生一個 test-command-creates.txt 的檔案,裡面是日期。 這裡刻意使用了 >> ,來確認新的內容會被附加到現有的檔案內容之後。

接著,寫一個 playbook 來呼叫該指令檔

---
# test-command-creates.yml
- name: 測試 command 的 creates
  hosts: all

  tasks:
    - name: 當 /tmp/test-command-creates.txt 不存在時,才執行。
      command: ./test-command-creates.sh
      args:
        creates: /tmp/test-command-creates.txt

然後執行

ansible-playbook -i localhost, -c local test-command-creates.yml

你會在執行結果中看到如下的字樣

TASK [當 /tmp/test-command-creates.txt 不存在時,才執行。] ***
changed: [localhost]

表示被執行了,用 cat /tmp/test-command-creates.txt 可以看到檔案內有目前的日期。

接著再次執行一次 plybook

ansible-playbook -i localhost, -c local test-command-creates.yml

執行結果就只有

TASK [當 /tmp/test-command-creates.txt 不存在時,才執行。] ***
ok: [localhost]

檢查 /tmp/test-command-creates.txt,可以看到是之前的日期,沒有新的行,內容也沒被變更。 看到這裡,相信你已經知道怎麼去應用 command 的 creates 了。

後面,我們會介紹另外一個跟 command 很相近的模組:shell