【问题标题】:Custom commands with libssh带有 libssh 的自定义命令
【发布时间】:2016-05-17 01:44:18
【问题描述】:

我正在使用 SSH 与 condor 服务器通信,需要调用命令进行自定义控制(即condor_submitcondor_makecondor_q 等)。在我的 Xcode 项目中下载并成功集成了 libSSH(是的,我使用的是 Mac OS),我发现提供的功能不支持自定义命令。教程说明这将在主机上执行命令:


rc = ssh_channel_request_exec(channel, "ls -l");
if (rc != SSH_OK) {
  ssh_channel_close(channel);
  ssh_channel_free(channel);
  return rc;
}

Source

然而,当我用 "condor_q" 替换 "ls -l" 时,该命令似乎没有执行。我设法通过使用这样的交互式 shell 会话来解决这个问题:


// Create channel

rc = ssh_channel_request_pty(channel);
if (rc != SSH_OK) return rc;
rc = ssh_channel_change_pty_size(channel, 84, 20);
if (rc != SSH_OK) return rc;
rc = ssh_channel_request_shell(channel);

std::string commandString = "condor_q";
char buffer[512];
int bytesRead, bytesWrittenToConsole;
std::string string;

while (ssh_channel_is_open(channel) && !ssh_channel_is_eof(channel)) {
    // _nonblocking
    bytesRead = ssh_channel_read_nonblocking(channel, buffer, sizeof(buffer), 0);
    if (bytesRead < 0) {
        rc = SSH_ERROR;
        break;
    }
    if (bytesRead > 0) {
        for (int i = 0; i < bytesRead; i++) {
            string.push_back(buffer[i]);
        }
        bytesWrittenToConsole = write(1, buffer, bytesRead);
        if (string.find("$") != std::string::npos) {

            if (commandString.length() > 0) {
                ssh_channel_write(channel, commandString.c_str(), commandString.length());
                ssh_channel_write(channel, "\n", 1);
            } else {
                break;
            }
            commandString.clear();
            string.clear();
        }
    }
}

// Distroy channel

所以我的问题是,有没有一种更简单的方法可以通过 SSH 发送 custom 命令,而不必“fake-send”命令?

谢谢

最大

【问题讨论】:

    标签: c++ shell custom-controls libssh condor


    【解决方案1】:

    自定义命令通常会转储到标准错误缓冲区中。

    因此,如果您使用自定义命令,请尝试使用如下所示的通道读取:

    rc = ssh_channel_read(channel, buffer, sizeof(buffer), 1);
    

    注意最后一个函数属性的 0 -> 1 变化。此属性告诉读取从通道上的 stderr 读取,其中一些信息可能被转储。

    试试看。

    【讨论】:

      【解决方案2】:

      rc = ssh_channel_request_exec(channel, "ls -l");

      成功返回码告诉你命令已成功发送到服务器,但并不表示已成功执行。您需要等待并检查退出代码或等待输出。

      你读了吗:

      http://api.libssh.org/stable/libssh_tutor_command.html

      并查看源代码中的examples/exec.c?

      【讨论】:

      • 示例文件包含的代码与他们的教程代码非常相似,所以这不是主要的帮助 :( 不过,你提到我需要等待输出,但是当运行一个会连续读取的循环时ssh 通道,不会返回任何内容。另外,您检查过我在代码下方发布的源吗?这与您发布的链接相同;)
      • 正如我告诉您的,要确保它已成功执行,您必须检查退出代码。 ssh_channel_request_exec() 的返回码告诉你它已经成功传输到服务器。服务器会告诉您它是否已使用退出代码成功执行它。通常交互式 shell 使用您自己的协议会更好,例如: ls && echo OK ||回声KO
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      • 1970-01-01
      • 2014-04-02
      • 2018-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多