这是一个有趣的情况,侧重于erlang ssh模块的行为.我花了几个小时来解决一个问题,结果证明Erlang ssh_connection*exec/4*函数是异步操作的.
如果发出ssh_connection:exec/4函数来运行需要几秒钟才能完成的脚本,然后在你的erlang程序中关闭ssh连接,脚本执行将终止.我的期望是ssh_connection:exec是同步的而不是异步的.
因为完成ssh_connection:exec调用的远程脚本的时间未知,所以我选择不发出关闭 ssh:close().我想了解其后果:
这是我用来验证此问题的测试erl程序的示例.作为脚本,您可以运行简单的睡眠10(睡眠10秒)来模拟慢速运行的程序.
-module(testssh).
-export([test/5]).
test (ServerName, Port, Command, User, Password) ->
crypto:start(),
ssh:start(),
{ok, SshConnectionRef} = ssh:connect(ServerName, Port, [ {user, User}, {password, Password} , {silently_accept_hosts, true} ], 60000 ),
{ok, SshConnectionChannelRef} = ssh_connection:session_channel(SshConnectionRef, 60000),
Status = ssh_connection:exec(SshConnectionRef, SshConnectionChannelRef, Command, 60000),
ssh:close(SshConnectionRef).
Run Code Online (Sandbox Code Playgroud)
远程脚本:
#!/bin/sh
sleep 10
Run Code Online (Sandbox Code Playgroud)
小智 4
我自己从未使用过 ssh 应用程序,但您应该读到一些错误的内容,文档中清楚地表明结果将作为消息传递给调用者:
[...] 结果将是根据以下模式的多条消息。请注意,最后一条消息将是通道关闭消息,因为 exec 请求是一次性执行,完成后将关闭通道[...]
请参阅http://www.erlang.org/doc/man/ssh_connection.html#exec-4
因此,在调用 ssh_connection:exec/4 后,使用如下循环进行测试:
wait_for_response(ConnectionRef) ->
receive
{ssh_cm, ConnectionRef, Msg} ->
case Msg of
{closed, _ChannelId} ->
io:format("Done");
_ ->
io:format("Got: ~p", [Msg]),
wait_for_response(ConnectionRef)
end
end.
Run Code Online (Sandbox Code Playgroud)
您应该收到命令输出和其他 ssh 消息,最后是一条“关闭”消息,这是 ssh 命令已正确完成的信号。
| 归档时间: |
|
| 查看次数: |
1417 次 |
| 最近记录: |