这是一个有趣的情况,主要关注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).
远程脚本:
#!/bin/sh
sleep 10
答案 0 :(得分: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.
您应该收到命令输出和其他ssh消息,最后是“关闭”消息,这是ssh命令已正确完成的信号。