Question

I have a Python routine which invokes some kind of CLI (e.g telnet) and then executes commands in it. The problem is that sometimes the CLI refuses connection and commands are executed in the host shell resulting in various errors. My idea is to check whether the shell prompt alters or not after invoking the CLI.

The question is: how can I get the shell prompt string in Python?

Echoing PS1 is not a solution, because some CLIs cannot run it and it returns a notation-like string instead of the actual prompt:

SC-2-1:~ # echo $PS1
\[\]\h:\w # \[\]

EDIT

My routine:

def run_cli_command(self, ssh, cli, commands, timeout = 10):
    ''' Sends one or more commands to some cli and returns answer. '''
    try:
        channel = ssh.invoke_shell()
        channel.settimeout(timeout)
        channel.send('%s\n' % (cli))
        if 'telnet' in cli:
            time.sleep(1)
        time.sleep(1)
        # I need to check the prompt here
        w = 0
        while (channel.recv_ready() == False) and (w < timeout):
            w += 1
            time.sleep(1)
        channel.recv(9999)
        if type(commands) is not list:
            commands = [commands]
        ret = ''
        for command in commands:
            channel.send("%s\r\n" % (command))
            w = 0
            while (channel.recv_ready() == False) and (w < timeout):
                w += 1
                time.sleep(1)
            ret += channel.recv(9999) ### The size of read buffer can be a bottleneck...
    except Exception, e:
        #print str(e) ### for debugging
        return None
    channel.close()
    return ret

Some explanation needs here: the ssh parameter is a paramiko.SSHClient() instance. I use this code to login to a server and from there I call another CLI which can be SSH, telnet, etc.

Was it helpful?

Solution

I’d suggest sending commands that alter PS1 to a known string. I’ve done so when I used Oracle sqlplus from a Korn shell script, as coprocess, to know when to end reading data / output from the last statement I issued. So basically, you’d send:

PS1='end1>'; command1

Then you’d read lines until you see "end1>" (for extra easiness, add a newline at the end of PS1).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top