ansible.builtin.shell

shell 是用來執行指令用的,等等,command 不也一樣嗎?。

對,其實大同小異,但有個很重要的差別,就是 pipe 或重導向 。 command 只能執行單一個指令,若需要作 pipe 串接或重導向時,就需要用到 shell 了。

這裡簡單舉四個例子,第一個是 iconv ,第二個是 grep,第三個是 awk,最後一個則是 expect 的範例。

- name: 轉換編碼
  shell: "iconv -f big5 -t utf-8 big5.txt > utf-8.txt"
  register: iconv_result
  ignore_errors: true

- debug:
    var: iconv_result

iconv 這個指令在轉換後,會把轉換結果直接輸出到 stdout,所以如果要存為檔案的話,就會需要用到 > 導向。

來看第二個例子:

- name: 找所有檔名裡有 'log' 的檔案
  shell: ls -l | grep log

這個例子用到了 pipe,讓 grep 能依據 stdin 去搜尋 log。

再來看第三個例子

- name: 找 /etc/passwd 裡,所有帳號開頭為 i,後面跟著 7 個或 8 個數字的帳號,輸出為檔案
  shell: "awk -F: '/^i[0-9]{7,8}/{print $1;}' /etc/passwd > /tmp/output.txt"

這個則是利用 awk 來找,然後輸出到 /tmp/output.txt

最後一個是 expect 的例子:

- name: 利用 expect 去等待機器用 PXE 開機起來。
  shell: |
    set timeout 300
    spawn ssh admin@{{ cimc_host }}

    expect "password:"
    send "{{ cimc_password }}\n"

    expect "\n{{ cimc_name }}"
    send "connect host\n"

    expect "pxeboot.n12"
    send "\n"

    exit 0
  args:
    executable: /usr/bin/expect

spawn 是啟動一個用 ssh 去連線的程序,接著用 expect 去等待特定的訊息出現,然後再送出準備好的回答。

看到這邊,相信你可以理解 shell 跟 command 的差異了。