iT邦幫忙

2021 iThome 鐵人賽

DAY 16
1
Software Development

系統與服務雜談系列 第 16

xargs - Linux裡好用的工具

xargs

xargs原來意思是build and execute command lines frooom standarad input(stdin)
xargs把從stdin接受到的字串, 轉成後面命令的參數, 來執行後面的命令.

為什麼講這個命令呢?
之前介紹grep、sed、awk,
grep找到的內容可以給sed、awk直接讀取
但若我是取出檔名, 要給後兩者讀取其內容呢?
這時xargs可以幫忙處理

# 搜尋txt檔案內容有it的, 顯示其檔名
grep -l 'it' *.txt                               
> aa.txt
> python.txt

# 透過xargs將檔名當成sed的參數, 來執行sed
grep -l 'it' *.txt | xargs sed -n 's/it/ithome/p'
> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active

轉個思維表示;
系統內的日誌也是能grep找出來含內容的檔案, 再轉給awk做格式轉換製作表格後,
再輸出到類似kibana等等的地方做儲存展示.
也能是用grep轉到執行自己寫的程式, 將檔名當成參數.

option介紹

xargs預設是用空格做完分隔符號, 也就是說,

echo "aa.txt python.txt" | xargs sed -n 's/it/ithome/p'
> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active

xargs會將"aa.txt python.txt"按照空格切成aa.txt、python.txt,
傳給sed當參數sed -n 's/it/ithome/p' aa.txt python.txt, 然後執行.

也能指定分隔符號, 透過-ddelimiter,

# 指定@為分隔符號
echo '11@22@33' | xargs -d '@' echo         
> 11 22 33

也能指定EOF符號-E, 表示讀到EOF就不會再讀取字串, 也不會去執行命令
ps 但無法跟上一個-d一起混用

# 指定22為EOF, 因此33就不被讀取, 22是不被拿去echo給執行去
echo '11 22 33' | xargs -E '22'  echo       
> 11

透過-tverbose, 能把要執行的命令給輸出出來, 並且執行該命令

# 能看到真正要執行的命令
grep -l 'it' *.txt | xargs -t sed -n 's/it/ithome/p'   
> sed -n s/it/ithome/p aa.txt python.txt 
> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active

透過-pinteractive, 這命令就只是一個prompt, 詢問是否要執行, 輸入y/Y, 就真正執行該命令
通常會跟上一個-t搭配使用

grep -l 'it' *.txt | xargs -tp sed -n 's/it/ithome/p'
# 會顯示命令並且等待用戶輸入,  這裡我輸入y
> sed -n s/it/ithome/p aa.txt python.txt ?...y

> baseurl=https://xxx/mysql-repo/yum/mysql-5.7-communithomey/el/$releasever/$basearch
> 13Th Ithome is my favorithomee active

玩一下之前學到的,做組合拳
先開一個新的terminal, 掛著讓它跑

ping -i 1 8.8.8.8 

再開另一個terminal
然後透過ps找到這執行中的PID, 透過xargs傳給kill執行

ps -ef | grep 'ping -i' | awk '{print $2}' | xargs -t  kill -9
> kill -9 242585 242668 
> kill: (242241): No such process

執行完, 原本持續在ping的process就會收到kill訊號而被kill.
這裡用到之前的grep+awk

掌握這些基本也能, 做到說像是去redis找到key, 然後再去刪除key

./redis-cli -h 127.0.0.1 -p 6381 -n 1 KEYS "ithome:*" | xargs ./redis-cli -h 127.0.0.1 -p 6381 -n 1 DEL

本日小結

很多組合的操作, 其實大多都能通過xargs中間轉一手來處理.
因為不是每個工具都支持pipeline的使用,
有xargs就能讓這些不支持的程式, 可以使用前一個命令完成之後的結果.
真的是個很方便的工具

----參考來源
鳥哥Linux私房菜 xargs


上一篇
sed - 7 常見案例
下一篇
設定檔格式INI + Service的管理工具Systemd簡介
系列文
系統與服務雜談32

尚未有邦友留言

立即登入留言