Zsh 开发指南(第十七篇 使用 socket 文件和 TCP 实现进程间通讯)

导读

就像我以前提到的,zsh 脚本是能够直接使用 socket 文件(UNIX domain socket 所使用)或者 TCP 和其余进程通讯的。若是进程都在本地,用 socket 文件效率更高些,而且不要占用端口,权限也更好控制。若是是在不一样机器,可使用 TCP。git

Socket 文件

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

使用 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。

相关文章
相关标签/搜索