就像我以前提到的,zsh 腳本是能夠直接使用 socket 文件(UNIX domain socket 所使用)或者 TCP 和其餘進程通訊的。若是進程都在本地,用 socket 文件效率更高些,而且不要佔用端口,權限也更好控制。若是是在不一樣機器,可使用 TCP。git
UNIX domain socket 是比管道更先進的進程通訊方法,是全雙工的方式,而且穩定性更好。但性能比管道差一些,不過通常性能瓶頸都不會出如今這裏,不用考慮性能問題。並且在一個 socket 文件上能夠創建多個鏈接,更容易管理。另外若是通訊方式從 socket 文件改爲 TCP,只須要修改不多的代碼(創建和關閉鏈接的代碼稍微改一下),而從管道改爲 TCP 則要麻煩不少。github
因此建議用 zsh 寫進程交互腳本的話,直接使用 socket 文件,而不是命名管道(匿名管道就能知足需求的簡單場景忽略不計)。bash
Socket 文件的用法:微信
# 監聽鏈接端
# 首先要加載 socket 模塊
% zmodload zsh/net/socket
% zsocket -l test.sock
% listenfd=$REPLY
# 此處阻塞等待鏈接
% zsocket -a $listenfd
# 鏈接創建完成
% fd=$REPLY
% echo $fd
5
# 而後 $fd 就可讀可寫
% cat <&$fd
good複製代碼
# 發起鏈接端
# 首先要加載 socket 模塊
% zmodload zsh/net/socket
% zsocket test.sock
# 鏈接創建完成
% fd=$REPLY
% echo $fd
4
# 而後 $fd 就可讀可寫
% echo good >&$fd複製代碼
鏈接創建後,怎麼用就隨意了。實際使用時,要判斷 fd 看鏈接是否正常創建了。一般使用 socket 文件要比在網絡環境使用 TCP 穩定性高不少,通常不會鏈接中斷或者出其餘異常。另外能夠在 zsocket 後加 -v 參數,查看詳細的信息(好比使用的 fd 號)。網絡
關閉鏈接:dom
# 發起鏈接端
# fd 是以前存放 fd 號的變量,不須要加 $
% exec {fd}>&-
# 監聽鏈接端
% exec {listenfd}>&-
% exec {fd}>&-
# 刪除 socket 文件便可,若是下次再使用會從新建立,該文件不能重複使用
% rm test.sock複製代碼
使用 TCP 鏈接的方式和使用 socket 文件基本同樣。socket
# 監聽鏈接端
# 首先要加載 tcp 模塊
% zmodload zsh/net/tcp
% ztcp -l 1234
% listenfd=$REPLY
# 此處阻塞等待鏈接
% ztcp -a $listenfd
# 鏈接創建完成
% fd=$REPLY
% echo $fd
3
# 而後 $fd 就可讀可寫
% cat <&$fd
good複製代碼
# 發起鏈接端
# 首先要加載 tcp 模塊
% zmodload zsh/net/tcp
% ztcp 127.0.0.1 1234
# 鏈接創建完成
% fd=$REPLY
% echo $fd
3
# 而後 $fd 就可讀可寫
% echo good >&$fd複製代碼
關閉鏈接:tcp
# 發起鏈接端
# fd 是以前存放 fd 號的變量
% ztcp -c $fd
# 監聽鏈接端
% ztcp -c $listenfd
% ztcp -c $fd複製代碼
recv_tcp,監聽指定端口,並輸出發送過來的消息。使用方法:recv_tcp 端口ide
#!/bin/zsh
zmodload zsh/net/tcp
(($+1)) || {
echo "Usage: ${0:t} port"
exit 1
}
ztcp -l $1
listenfd=$REPLY
[[ $listenfd == <-> ]] || exit 1
while ((1)) {
ztcp -a $listenfd
fd=$REPLY
[[ $fd == <-> ]] || continue
cat <&$fd
ztcp -c $fd
}複製代碼
send_tcp,用來向指定機器的指定端口發一條消息。使用方法:send_tcp 機器名 端口 消息 (機器名可選,若是沒有則發到本機,消息能夠包含空格)性能
#!/bin/zsh
zmodload zsh/net/tcp
(($# >= 2)) || {
echo "Usage: ${0:t} [hostname] port message"
exit 1
}
if [[ $1 == <0-65535> ]] {
ztcp 127.0.0.1 $1
} else {
ztcp $1 $2
shift
}
fd=$REPLY
[[ "$fd" == <-> ]] || exit 1
echo ${*[2,-1]} >&$fd
ztcp -c $fd複製代碼
本文介紹了使用 socket 文件或者 TCP 來實現兩個腳本之間通訊的方法。
全系列文章地址:github.com/goreliu/zsh…
付費解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領域相關問題,靈活訂價,歡迎諮詢,微信 ly50247。