1

I started using paramiko for invoking commands on my server from python script on my computer.

I wrote the following code:

from paramiko import client

class ssh:
    client = None

    def __init__(self, address, port, username="user", password="password"):
        # Let the user know we're connecting to the server
        print("Connecting to server.")
        # Create a new SSH client
        self.client = client.SSHClient()
        # The following line is required if you want the script to be able to access a server that's not yet in the known_hosts file
        self.client.set_missing_host_key_policy(client.AutoAddPolicy())
        # Make the connection
        self.client.connect(address, port, username=username, password=password, look_for_keys=False)

    def sendcommand(self, command):
        # Check if connection is made previously
        if self.client is not None:
            stdin, stdout, stderr = self.client.exec_command(command)
            while not stdout.channel.exit_status_ready():
                # Print stdout data when available
                if stdout.channel.recv_ready():
                    # Retrieve the first 1024 bytes
                    _data = stdout.channel.recv(1024)
                    while stdout.channel.recv_ready():
                        # Retrieve the next 1024 bytes
                        _data += stdout.channel.recv(1024)

                    # Print as string with utf8 encoding
                    print(str(_data, "utf8"))
        else:
            print("Connection not opened.")


    def closeconnection(self):
        if self.client is not None:
            self.client.close()

def main():
    connection = ssh('10.40.2.222', 2022 , "user" , "password")
    connection.sendcommand("cd /opt/process/bin/; ./process_cli; scm")    
    print("here")

    #connection.sendcommand("yes")
    #connection.sendcommand("nsgadmin")
    #connection.sendcommand("ls")

    connection.closeconnection()

if __name__ == '__main__':
    main()

Now , the last command in the command I am sending to my server (scm) is a command that is should be sent to the process "process_cli" that I am running in the server and should print me the output of the process (the process gets input from the stdin of the server's shell and printing the output to the stdout of the server's shell).
When I am running in interactive mode everything ok but when I running the script I get success with connecting to my server and running all the basic shell commands on this server (example: ls , pwd etc.) but I can't run any commands on the process that is running inside this server.

How can I fix this issue?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
ms_stud
  • 361
  • 4
  • 18

1 Answers1

0

SSH "exec" channel (which is used by SSHClient.exec_command) executes each command in a separate shell. As a consequence:

  1. cd /opt/process/bin/ will have no effect at all on ./process_cli.
  2. scm will be executed as a shell command, not as a sub-command of process_cli.

You need to:

  1. Execute cd and process_cli as one command (in the same shell):

    stdin, stdout, stderr = client.exec_command('cd /opt/process/bin/ && ./process_cli') 
    

    or

    stdin, stdout, stderr = client.exec_command('/opt/process/bin/process_cli') 
    
  2. Feed the (sub)commands of process_cli to its standard input:

    stdin.write('scm\n')
    stdin.flush()
    

Similar questions:

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992