如何在Erlang中使用ssh_connection:exec?

时间:2013-06-07 01:55:49

标签: erlang

这是一个有趣的情况,主要关注erlang ssh模块的行为。我花了几个小时来解决一个问题,结果证明Erlang ssh_connection * exec / 4 *函数运行异步

如果您发出ssh_connection:exec/4函数来运行需要几秒钟才能完成的脚本,然后在您的erlang程序中关闭ssh连接,脚本执行将终止。我的期望是ssh_connection:exec将同步而不是异步。

由于完成ssh_connection:exec调用的远程脚本的时间未知,我选择不发出闭包 ssh:close()。我想了解其后果:

  • gc会在某个时候清除它吗?
  • 在整个节点存在期间它会保持开放状态吗?
  • 有没有办法让ssh_connection:exec同步,正如我认为的那样。

以下是我用来验证此问题的测试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

1 个答案:

答案 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命令已正确完成的信号。