我最近正在编写一段代码,以使用SSH访问外部服务器,然后与我直接通过它连接到的交互式外壳式应用程序进行通信。
我正在使用仅提供基本库的嵌入式Linux,无法使用任何其他软件或库。另外,我必须通过应用程序内部的C / C ++代码来完成此操作。因此,我决定使用管道和read(),write()系统调用,而我会坚持使用。
我写了一些代码来更好地理解和测试这个概念。但是它没有按预期工作。我使用了一个片段from here。似乎工作正常,但是main中的循环表现不如预期
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
static bool
start_subprocess(char *const command[], int *pid, int *infd, int *outfd)
{
int p1[2], p2[2];
if (!pid || !infd || !outfd)
return false;
if (pipe(p1) == -1)
goto err_pipe1;
if (pipe(p2) == -1)
goto err_pipe2;
if ((*pid = fork()) == -1)
goto err_fork;
if (*pid) {
/* Parent process. */
*infd = p1[1];
*outfd = p2[0];
close(p1[0]);
close(p2[1]);
return true;
} else {
/* Child process. */
dup2(p1[0], STDIN_FILENO);
dup2(p2[1], STDOUT_FILENO);
close(p1[0]);
close(p1[1]);
close(p2[0]);
close(p2[1]);
execvp(*command, command);
/* Error occured. */
fprintf(stderr, "error running %s: %s", *command, strerror(errno));
abort();
}
err_fork:
close(p2[1]);
close(p2[0]);
err_pipe2:
close(p1[1]);
close(p1[0]);
err_pipe1:
return false;
}
int main() {
char *cmd[4];
cmd[0] = "/usr/bin/ssh";
cmd[1] = "-tt";
cmd[2] = "user@localhost";
cmd[3] = NULL;
char buf[65535];
char msg[65535];
int pid, infd, outfd;
start_subprocess(cmd, &pid, &infd, &outfd);
printf ("Started app %s as %d\n\n", *cmd, pid);
while(1) {
read(outfd, buf, 65535);
printf(">>> %s\n", buf);
printf("<<< ");
scanf("%s", msg);
if(strcmp(msg, "exit") == 0) break;
write(infd, msg, strlen(msg));
}
return 0;
}
我已经尝试了各种SSH -t设置,并且似乎在某种程度上启用了-tt选项(据我所知,它强制使用伪终端),没有它,我会得到
Pseudo-terminal will not be allocated because stdin is not a terminal.
所以我认为 -tt 在这里是正确的。但是这种行为很奇怪。我想通过SSH连接,然后发出ls命令并查看输出,该输出应与普通SSH相似:
user@xubuntuLTS ~/dev/cpp/pipes$ ssh localhost
>>>> WELCOME TO SSH SERVER <<<<
Last login: Thu Jan 3 22:34:35 2019 from 127.0.0.1
user@xubuntuLTS ~$ ls
Desktop dev Documents Downloads Music Pictures Public Templates TEST_FILE Videos
user@xubuntuLTS ~$
但是请注意,我的应用程序是这样的:
user@xubuntuLTS ~/dev/cpp/pipes$ ./a.out
Started app /usr/bin/ssh as 18393
>>>> WELCOME TO SSH SERVER <<<<
>>> Last login: Thu Jan 3 22:35:28 2019 from 127.0.0.1
<<< ls
>>> user@xubuntuLTS ~$
<<<
ls
>>> ls0;user@xubuntuLTS: ~user@xubuntuLTS ~$
<<< ls
>>> ls0;user@xubuntuLTS: ~user@xubuntuLTS ~$
您能提示我代码中的错误吗?我想从终端读取与在“正常” SSH会话期间看到的输出完全相同的输出,可能在每个read()调用期间具有“附加”输出,因此我可以通过这种类型的交互式通信轻松地执行一些自动化任务。请注意,这里使用标准终端只是一个示例,在实际解决方案中,我直接通过SSH登录来连接某种命令行界面程序,而无需实际访问shell。
我很确定这里正确使用write()和read()会出问题,但是我不是这方面的专家。