Page MenuHomePhabricator

"cd outputFolder" - changed directory successfully, but it always returns the root directory "/" when I execute the command - "pwd"
Open, Needs TriagePublic

Description

Below program changes the current directory successfully, but it always returns the root directory.
rc = ssh_channel_request_exec(channel, "cd outputFolder"); - It has changed the current directory.
rc = ssh_channel_request_exec(channel, "pwd"); - It always returns the root directory.

Could some one help me on this. why it always returns the root directory, though previous api function has changed the root directory to outputFolder directory. Below is the screen shot as well as source code is attached for the reference.

#include "stdafx.h"
#include "libssh.h"
#include "sftp.h"
#include <stdlib.h>
#include <stdio.h> 
#include <string>

int main(int argc, char* argv[])
{
   int  verbose   = SSH_LOG_PROTOCOL;
    int  port      = 22;
    int  rc        = 0;
    char *username = "mytestsftp";
    char *passwd   = "as4ko3#45";
    int  nbytes;

    char buffer[1024];
    memset(buffer, 0, 1024);
    std::string pBuffer("");


    ssh_session my_ssh_session = ssh_new();
    if (my_ssh_session == NULL)
        exit(-1);

    ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "72.82.243.214");
    ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT,  &port);
    ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbose);
  
    rc = ssh_connect(my_ssh_session);
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));

    rc = ssh_userauth_password(my_ssh_session, username, passwd);
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));

    ssh_channel channel;
    channel = ssh_channel_new(my_ssh_session);   
    rc          = ssh_channel_open_session(channel);
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));
    
    rc = ssh_channel_request_exec(channel, "cd outputFolder");
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));

    ssh_channel_close(channel);

    channel = ssh_channel_new(my_ssh_session);   
    rc      = ssh_channel_open_session(channel);
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));
    
    rc = ssh_channel_request_exec(channel, "pwd");
    printf("conn: ok=?%d, %d, %s\n", rc==SSH_OK, rc, ssh_get_error(my_ssh_session));

	if (rc == SSH_OK)
	{
		//Reading from the channel..
		nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
		while (nbytes > 0)
		{
			pBuffer.append(buffer);
			nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
		}
	}

    printf("current directory is = %s",pBuffer.c_str());

    ssh_channel_close(channel);
    ssh_channel_free(channel);

    ssh_disconnect(my_ssh_session);
    ssh_free(my_ssh_session);

    return 0;
}

Event Timeline

Lakkan created this task.Aug 12 2020, 12:48 PM
Lakkan updated the task description. (Show Details)Aug 12 2020, 12:55 PM
Jakuje added a subscriber: Jakuje.Aug 12 2020, 1:00 PM

The ssh_channel_request_exec() executes separate command in separate ssh execute channel, which on the server results in starting a new shell, executing a command and exiting. Running separate commands this way does not work if you want the one affect the other. If you need this behavior, you should check how to open a shell, feed it with commands and read the output as described in the following chapter of the tutorial: https://api.libssh.org/stable/libssh_tutor_shell.html

Or you can send the commands togeter as "cd outputFolder && pwd", which should give you the expected result.

Lakkan added a comment.EditedAug 12 2020, 5:20 PM

My requirement is as below:

case1: I need to set the current directory - then get the contents of the directory.
case2: I need to set he current directory - then get the current directory. there may be more scenarios like that.

For that, do I need to create single channel, After that immediately associate the channel with "pty"

For Ex:-

 ssh_channel channel;   - create a global variable
 channel = ssh_channel_new(session);   - In the constructor or during initialization of session
 
 then connect the channel to the "pseudo-teletype"
 
 ssh_channel_request_pty(channel);
 ssh_channel_change_pty_size(channel, 80, 24);

 After this how to execute the command- Do I still need to use - ssh_channel_request_exec() for execution of commands.

 rc = ssh_channel_request_shell(channel);
   
 while (ssh_channel_is_open(channel) &&  !ssh_channel_is_eof(channel))
 {
     nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
     if (nbytes > 0)
        write(1, buffer, nbytes);
 }
 
Please let me know,  Is this right way to execute the commands on connected terminal. If you some sample please post me here.
Thanks