通过像 Unix/Linux 中的期望脚本一样通过 c++ 提供登录名和密码

Posted

技术标签:

【中文标题】通过像 Unix/Linux 中的期望脚本一样通过 c++ 提供登录名和密码【英文标题】:Providing login and password through c++ like expect script in Unix/Linux 【发布时间】:2010-12-18 08:19:02 【问题描述】:

问题 ::

我想通过 SSH 远程登录到服务器并执行一些命令并检索执行命令的输出。

解决方案 ::

我在我的 perl 脚本中使用我的“期望脚本”实现了同样的效果,然后对其进行处理。但是,它太慢了,大约需要 10 秒才能获取远程进程的 PID,然后检查其内存和 CPU 使用率。

使用 ssh-keygen 生成 rsa ID 是一种选择,但双向通信仍然是个问题。

要求 ::

是否可以在 C/C++ 中实现相同的目标,而无需使用管道或 FIFO 使用任何额外的库?

Popen() 似乎是一个选项,但它只是单向的(仅 *BSD 存在双向)并且使用 FIFO,我不知道如何使 ssh 命令输入和输出附加到 FIFO 并且 SSH 命令需要登录和密码总是来自终端。

提前致谢。

【问题讨论】:

fork() 和 exec() 能解决问题吗?如果我 dup2() 子进程的标准输入和标准输出,然后执行 SSH 命令。 真正的问题是是什么让您的脚本变慢:执行速度、带宽或延迟。但这当然是可能的。 【参考方案1】:

这是可能的,但是需要大量的工作,并且完成此操作的完整程序太长,无法在此处发布。尤其是在读取和写入交错时应考虑 I/O 缓冲。不过,一个单一的写入阶段和一个单一的读取阶段会很容易。

无论如何,我建议使用socketpair 而不是管道。这些允许双向通信,而管道是单向的(因此您需要两个管道,即四个文件描述符)。

enum  FROMCHILD = 0, TOCHILD = 1 ;
int fd[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, fd); // check for errors

switch (fork()) 
  case -1:
    // handle error
  case 0:
    // child
    dup2(fd[TOCHILD],   0);
    dup2(fd[FROMCHILD], 1);
    // try to exec
    _exit(1);
  default:
    // parent: we may read from fd[FROMCHILD] and write to fd[TOCHILD]

此外,如果您需要将 SSH 命令构造/解析到 argv 样式的缓冲区中,请确保引用正确。如果您需要示例代码(或对问题的讨论),请查看 Git 中的 quote.c

【讨论】:

是的,你是对的。根据我的时间表来实施它需要一些时间。

以上是关于通过像 Unix/Linux 中的期望脚本一样通过 c++ 提供登录名和密码的主要内容,如果未能解决你的问题,请参考以下文章

Windows 和 Linux 中的换行与回车的区别,Windows下编写的Shell脚本,直接放到linux/unix下执行会报错

10个UNIX/LINUX的命令行神器

Ubuntu-18.04不能像ubuntu14一样通过编辑rc.local来设置开机启动脚本

像广播电台一样通过 HTTP 广播音频

Unix/Linux shell脚本中 “set -e” 的作用

通过adobe flash cc创建一个像SWF flash格式的停靠栏一样的栏[关闭]