C++ 使用libssh的自定义命令

C++ 使用libssh的自定义命令,c++,shell,custom-controls,libssh,condor,C++,Shell,Custom Controls,Libssh,Condor,我正在使用SSH与condor服务器通信,需要调用用于自定义控制的命令(即,condor\u submit,condor\u make,condor\u q,等等)。在我的Xcode项目中下载并成功集成了libSSH(是的,我使用的是Mac OS),我发现提供的函数不支持自定义命令。本教程说明,这将在主机上执行命令: rc = ssh_channel_request_exec(channel, "ls -l"); if (rc != SSH_OK) { ssh_channel_close(

我正在使用SSH与condor服务器通信,需要调用用于自定义控制的命令(即,
condor\u submit
condor\u make
condor\u 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;
}

但是,当我将
“ls-l”
替换为
“condor\u q”
时,命令似乎没有执行。我通过使用交互式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

//创建频道
rc=ssh\u channel\u request\u pty(通道);
如果(rc!=SSH_OK)返回rc;
rc=ssh_channel_change_pty_size(通道,84,20);
如果(rc!=SSH_OK)返回rc;
rc=ssh\u channel\u request\u shell(channel);
std::string commandString=“condor_q”;
字符缓冲区[512];
int字节读,字节写的tentoconsole;
std::字符串;
而(ssh_通道是开放的(通道)&!ssh_通道是开放的(通道)){
//非阻塞
bytesRead=ssh\u channel\u read\u nonblocking(通道,缓冲区,sizeof(缓冲区),0);
如果(字节读取<0){
rc=SSH_错误;
打破
}
如果(字节读取>0){
for(int i=0;i0){
ssh_channel_write(channel,commandString.c_str(),commandString.length());
ssh_通道_写入(通道“\n”,1);
}否则{
打破
}
commandString.clear();
string.clear();
}
}
}
//扣押通道
那么我的问题是,有没有一种更简单的方法可以通过SSH发送自定义命令,而不必“假发送”命令

谢谢


Max

rc=ssh\u channel\u request\u exec(通道,“ls-l”)

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

你读过:


请看源代码中的示例/exec.c?

自定义命令通常会转储到stderr缓冲区中

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

rc = ssh_channel_read(channel, buffer, sizeof(buffer), 1);
注意最后一个函数属性上的0->1更改。该属性告诉read从可能转储某些信息的通道上的stderr读取


试试看。

示例文件包含的代码与他们的教程代码非常相似,因此没有什么帮助:(尽管如此,您提到我需要等待输出,但是当运行一个将持续读取ssh通道的循环时,将不会返回任何内容。此外,您是否检查了我在代码下面发布的源代码?这与您发布的链接相同;)正如我告诉您的,为了确保它已成功执行,您必须检查退出代码告诉您它已成功传输到服务器。服务器会告诉您是否已使用退出代码成功执行它。通常,使用您自己的协议(如:ls&&echo OK | | echo KO)使用交互式shell会更好