Implement an interactive shell over ssh in Python using Paramiko?

前端 未结 1 690
慢半拍i
慢半拍i 2020-11-27 17:56

I want to write a program (in Python 3.x on Windows 7) that executes multiple commands on a remote shell via ssh. After looking at paramikos\' exec_command() fu

相关标签:
1条回答
  • 2020-11-27 18:02
    import paramiko
    import re
    
    
    class ShellHandler:
    
        def __init__(self, host, user, psw):
            self.ssh = paramiko.SSHClient()
            self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.ssh.connect(host, username=user, password=psw, port=22)
    
            channel = self.ssh.invoke_shell()
            self.stdin = channel.makefile('wb')
            self.stdout = channel.makefile('r')
    
        def __del__(self):
            self.ssh.close()
    
        def execute(self, cmd):
            """
    
            :param cmd: the command to be executed on the remote computer
            :examples:  execute('ls')
                        execute('finger')
                        execute('cd folder_name')
            """
            cmd = cmd.strip('\n')
            self.stdin.write(cmd + '\n')
            finish = 'end of stdOUT buffer. finished with exit status'
            echo_cmd = 'echo {} $?'.format(finish)
            self.stdin.write(echo_cmd + '\n')
            shin = self.stdin
            self.stdin.flush()
    
            shout = []
            sherr = []
            exit_status = 0
            for line in self.stdout:
                if str(line).startswith(cmd) or str(line).startswith(echo_cmd):
                    # up for now filled with shell junk from stdin
                    shout = []
                elif str(line).startswith(finish):
                    # our finish command ends with the exit status
                    exit_status = int(str(line).rsplit(maxsplit=1)[1])
                    if exit_status:
                        # stderr is combined with stdout.
                        # thus, swap sherr with shout in a case of failure.
                        sherr = shout
                        shout = []
                    break
                else:
                    # get rid of 'coloring and formatting' special characters
                    shout.append(re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]').sub('', line).
                                 replace('\b', '').replace('\r', ''))
    
            # first and last lines of shout/sherr contain a prompt
            if shout and echo_cmd in shout[-1]:
                shout.pop()
            if shout and cmd in shout[0]:
                shout.pop(0)
            if sherr and echo_cmd in sherr[-1]:
                sherr.pop()
            if sherr and cmd in sherr[0]:
                sherr.pop(0)
    
            return shin, shout, sherr
    
    0 讨论(0)
提交回复
热议问题