c++linuxexceptionlibssh

how to get output of a wrong command with libssh


I have this function which can connect to a remote system via ssh:


    std::string _ErrMsg;
    int _RetVal = 0;
    
    MyException errMsg;
    int port = 22;
    try
    {
        if (my_ssh_session == NULL) {
            std::cout << "Error creating ssh session" << std::endl;
            throw MyException("Error in creating session");
            _RetVal = -1;
            return _RetVal;
        }
        ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, (const void*)(authentication.ip));
        ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, (const void*)(authentication.userName));
        ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
        int rc = ssh_connect(my_ssh_session);
        if (rc != SSH_OK) {
            std::cout << "Error with connecting" << std::endl;
            _ErrMsg = ssh_get_error(my_ssh_session);
            ssh_free(my_ssh_session);
            _RetVal = -2;
            throw MyException(_ErrMsg);
        }
        rc = ssh_userauth_password(my_ssh_session, NULL, (const char*)(authentication.pw));
        if (rc != SSH_AUTH_SUCCESS) {
            std::cout << "Authentication failed " << ssh_get_error(my_ssh_session) << std::endl;
            _ErrMsg = ssh_get_error(my_ssh_session);
            ssh_disconnect(my_ssh_session);
            ssh_free(my_ssh_session);
            _RetVal = -3;
            throw MyException(_ErrMsg);
        }
    }
    catch (MyException& e)
    {
        throw e;
    }
    return _RetVal;

and this function which executes a command through ssh channel:

std::string ssh::exec_ssh_command(char* command)
{
    std::string receive = "";
    std::string err;
    int rc, nbytes;
    char buffer[2000];
    MyException errMsg;
    try {
        my_ssh_session = ssh_new();

        ssh_channel channel = ssh_channel_new(my_ssh_session);
        if (channel == NULL)
        {
            receive = "Channel allocation failed.";
            throw MyException(receive);
        }
        rc = ssh_channel_open_session(channel);
        if (rc != SSH_OK)
        {
            free_channel(channel);
            receive = "Opening session channel failed.";
            throw MyException(receive);
        }

        rc = ssh_channel_request_exec(channel, command);
        if (rc != SSH_OK) {
            receive = "Channel's request executing failed.";
            free_channel(channel);
            throw MyException(receive);
        }
        nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
        receive = buffer;
        if (nbytes > 0)
        {
            receive.erase(nbytes - 1, 2000);
        }
        else
        {
            receive = "Error in command: not found or wrong syntax";
            throw MyException(receive);
        }

        if (nbytes < 0)
        {
            receive = "Error in reading data from channel ";
            throw MyException(receive);
        }
        free_channel(channel);
        free_session(my_ssh_session);
    }
    catch (MyException& err)
    {
        throw err;

    }
    return receive;
}

I want to throw an exception when a wrong command is sent to this function. for example, if I send this command: ls /sys/class/net | se -n - 1p. if I run this command on terminal, I got this error : se: command not found.when I run it like this : ls /sys/class/net | sed -n -s 1p | grep 'something irrelevant', it gives nothing. it gives nothing as output in both ways. and nbytes will be 0. is there any way to take that se: command not found ??


Solution

  • Errors are printed on the stderr channel, which is distinct from the default stdout channel.

    The last argument of ssh_channel_read determines which is read: 0 for stdout, 1 for stderr. I suggest you read from both channels by calling ssh_channel_read twice.