Google+ Followers

2017年2月7日 星期二

[Linux] 使用 xargs 執行任務,參數不只接在指令尾部

原先很習慣用 find 找到東西後,搭配 -exec 去執行任務,這時要串起來的指令很方便。然而,若是要在一個清單內,找到東西後,再接一串指令時,就會試試 xargs 這指令。只是 xargs 習慣都是把變數接在指令後頭:

$ grep 我 user.dict | xargs -n 1 echo | head -n 5
分我杯羹
天知地知,你知我知
禮豈為我設
誨爾諄諄,聽我藐藐
惠子知我


此例就是找到的關鍵字”我”,再丟給 echo 去印出來。但如果,想要把找到的關鍵字都包起來時:

找到”分我杯羹”了
找到”天知地知,你知我知”了
找到”禮豈為我設”了
找到”誨爾諄諄,聽我藐藐”了
找到”惠子知我”了


這時就會卡卡的,沒錯,就派 shell 上場了:

$ grep 我 user.dict | xargs -n 1 sh -c 'echo "找到\"${@}"\"了' "${0}" | head -n 5
找到"分我杯羹"了
找到"天知地知,你知我知"了
找到"禮豈為我設"了
找到"誨爾諄諄,聽我藐藐"了
找到"惠子知我"了


如此一來,透過 sh 在包一層,就可以完美使用 xargs 做事了。而我真正的需求是檢查一個檔案清單,查看清單內的檔案是否都存在:

$ grep keyword file-list.txt | xargs -n 1 sh -c 'test -r "${@}" || echo "${@} NOT FOUND" ' "${0}"

2017年2月3日 星期五

Ansible 筆記 - 透過 Reverse SSH Tunnel 維護機器

有時候就是這樣,某些機器本身連不進去,這時要測試發佈流程時,就適合從中間機器建立 SSH Tunnel 啦。例如 A <-> B <-> C 關係中,B 可以分別連到 A 跟 C ,但 A 跟 C 彼此無法連上。這時就從 B 的角色建立個 Reverse SSH Tunnel 了

@B:

$ ssh -NR 2266:C_HOST_IP:22 [email protected]_HOST_IP


如此一來,在 A 機器中,就可以自連 ssh 127.0.0.1:2266 就可以直達 C 機器囉!

接著,若在 A 機器發動 ansible deploy 任務,就會有需要指定 ansible-playbook 運作時,那個 ssh port 要換一下,所幸的,用 ansible-playbook -h 就有教學啦 XD 其中 sftp 跟 scp/ssh 的參數名不一樣,所以得個別設定,完整的範例:

@A:

$ HOST=tag_Ansible_MY_Task DATA="['127.0.0.1']" ansible-playbook -i bin/echo.sh MY_Task.yml --private-key=ssh-private-key.pem --sftp-extra-args="-oPORT=2266" --scp-extra-args="-p 2266" --ssh-extra-args="-p 2266"


此例 bin/echo.sh 只是一個讓我組出 ansible-playbook 所需的格式:

$ cat bin/echo.sh
#!/bin/bash
echo "{\"$HOST\":$DATA}"
$ HOST=tag_Ansible_MY_Task DATA="['127.0.0.1']" bin/echo.sh
{"tag_Ansible_MY_Task":['127.0.0.1']}
$ head -n 7 MY_Task.yml
---
- hosts: tag_Ansible_MY_Task
  remote_user: ubuntu
  become: true
  become_user: root
  become_method: sudo