erlang 实现了 对 ssh 的支持,本文只讲述我本身对所理解的ssh 模块的部分理解,若是错误,烦请指出,万分感谢。算法
使用 ssh 模块,先要启动 ssh 功能: ssh:start()。erlang 的 ssh 分为 client 和 server 两部分。能够起一个 erlang 节点用来支持 server,也可使用 Linux 下默认的 22 号端口来支持 server(已经启动了 sshd 服务)。若是 起一个 erlang 节点做为 server的话,能够自定义不少特征,好比 端口改变,IP地址改变,加解密算法,记录日志函数,密钥,目录等等。使用 ssh:daemon() 函数进行启动。不过我没怎么研究过这个模式。shell
还能够 直接链接 22 号端口,server 部分由 sshd服务提供。session
client 就用一个 erlang 节点来处理。在A机器上面启动一个 erlang 节点,当成 ssh 的客户端,链接 B机器的 22 号端口,用来执行 B 机器上面的 shell 命令。A机器的操做步骤以下:ssh
1, ssh:start(). 启动 ssh 模块的功能。函数
2,获取 一个 ssh 链接。这个 Ref 指针是用来表示一个 ssh 链接的。指针
{ok,Ref}= ssh:connect("192.168.217.135",22,[]).日志
3,生成一个 ssh_channel_id() 。ssh_channel_id 是一个信道的标识,咱们后面要往这个信道发送shell 命令。下面的 1000 表示 超时时间是 1000 毫秒。server
{ok,ChannelId} = ssh_connection:session_channel(Ref,1000).进程
4,设置 该ssh 链接的 该信道 的通讯为 须要回复,若是不设置这个,那么你的 erlang 进程将会一直卡在 执行 shell 命令的那个地方,没法退出。我的以为缘由是 该ssh_channel_id 不可用。由于 exec 函数在执行 shell 命令成功以后,将会关闭这个 ssh_channel_id 。io
sh_connection:reply_request(Ref,true,success,ChannelId). 这个设置 返回值的 状态是 wanted 。要设置成这个才不会 卡死。
5,执行 远程命令
ssh_connection:exec(Ref,ChannelId,"/home/start.sh",1000).
须要注意的是,exec 函数执行成功以后,将会关闭 这个ChannelId,此时若是执行 ssh_connection:send_eof(Ref, ChannelId) 来关闭这个ChannelId 将会报错,因此下次你要调用 exec 函数的时候,记得先 执行 第3 步,生成一个 新的 ssh_channel_id ,而后执行 第4 步,将这个新的 ssh_channel_id 置为 须要回复,而后利用该 新的 ssh_channel_id 执行 第5 步。
这里还残留了一些问题,好比如何让 B机器上执行的 脚本的结果返回给 A机器的 erlang 节点,如何在 B机器上面启动节点处理 ssh server的消息,留待之后再深刻研究。