在pty模式下使用libssh的stderr

时间:2016-08-18 19:46:21

标签: c libssh

我使用libssh在远程服务器上执行命令。 这是我的代码(为简化起见,这里没有检查返回代码,但所有这些代码都没问题):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Snip -->
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>echo $(TargetName)</PostBuildEvent>
  </PropertyGroup>
</Project>

输出是有道理的:

#include <stdio.h>
#include <stdlib.h>
#include <libssh/libssh.h>

int main() {

    /* opening session and channel */
    ssh_session session = ssh_new();
    ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
    ssh_options_set(session, SSH_OPTIONS_PORT_STR, "22");
    ssh_options_set(session, SSH_OPTIONS_USER, "julien");
    ssh_connect(session);
    ssh_userauth_autopubkey(session, NULL);
    ssh_channel channel = ssh_channel_new(session);
    ssh_channel_open_session(channel);

    /* command execution */
    ssh_channel_request_exec(channel, "echo 'foo' && whoam");

    char *buffer_stdin = calloc(1024, sizeof(char));
    ssh_channel_read(channel, buffer_stdin, 1024, 0);
    printf("stdout: %s\n", buffer_stdin);
    free(buffer_stdin);

    char *buffer_stderr = calloc(1024, sizeof(char));
    ssh_channel_read(channel, buffer_stderr, 1024, 1);
    printf("stderr: %s", buffer_stderr);
    free(buffer_stderr);

    ssh_channel_free(channel);
    ssh_free(session);
    return EXIT_SUCCESS;
}

现在,如果我在stdout: foo stderr: command not found: whoam 之后添加对ssh_channel_request_pty的电话:

ssh_channel_open_session

不再有stderr输出:

    ...
    ssh_channel channel = ssh_channel_new(session);
    ssh_channel_open_session(channel);
    ssh_channel_request_pty(channel);
    ssh_channel_request_exec(channel, "echo 'foo' && whoam");
    ...

如果我通过以下方式更改命令:

stdout: foo
stderr:

现在在stdout上读取错误输出!

ssh_channel_request_exec(channel, "whoam");

我遗失了stdout: command not found: whoam stderr: 的内容?

有关信息,我使用它是因为在某些服务器上运行ssh_channel_request_pty命令时出现以下错误:

  

sudo:抱歉,你必须有一个tty来运行sudo

1 个答案:

答案 0 :(得分:2)

从概念上讲,pty表示终端(或者,甚至更低级别的串行端口) - 每个方向上只有一个通道。默认情况下,在pty中运行的进程的标准输出和标准错误都会转到同一位置。

(考虑一下在终端中运行命令时会发生什么 - 例如 - 如果你没有重定向任何东西,stdout和stderr都会出现在屏幕上,并且无法区分它们。)

一般来说,如果您需要以root身份远程自动运行命令,则应该以root用户身份登录,或者使用NOPASSWD选项授予用户sudo访问权限。不要自动输入密码。