cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3034
Views
3
Helpful
11
Replies

Unable to execute second python interact.send command in my script

ananthap
Cisco Employee
Cisco Employee

I am trying to write a python script which will do a ssh to Cisco VOS device (similar to CUCM).

I  am using paramiko Library and interact command in my python script. Able to successfully SSH the device, able to execute the first command. However second command is failing.

Here is sample code of my python script where is is not executing.

import paramiko
from paramiko_expect import SSHClientInteraction

sshsession = paramiko.SSHClient()
sshsession.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sshsession.connect("xx.xx.xx.xxx", username="xxx", password="xxx")
# "display=True" is just to show you what script does in real time. While in production you can set it to False
interact = SSHClientInteraction(sshsession, timeout=600, display=True)
# program will wait till session is established and  returns admin prompt
interact.expect('admin:')
# program runs show status command
interact.send('show status')
interact.expect('admin:')

/* This command is not executing*/
interact.send('utils service restart Engine')

 

Any suggesstions on why the above command is not getting executed ?

 

Rgds,

Anantha

 

1 Accepted Solution

Accepted Solutions

Marcel Zehnder
Spotlight
Spotlight

@ananthap based on the reply from @mradell , try this one:

from netmiko import ConnectHandler
import logging
import time

logging.basicConfig(filename='netmiko.log', level=logging.DEBUG)
logger = logging.getLogger("netmiko")

device = {
        "device_type": "generic",
        "ip": "xxx.xxx.xxx.xxx",
        "username": "xxx",
        "password": "xxx"
}

with ConnectHandler(**device) as ssh:
    prompt = r"admin:.*"
    commands = [
        "show status",
        "utils service restart Engine"
    ]

    time.sleep(20)

    for cmd in commands:
        output = ssh.send_command(cmd, expect_string=prompt, read_timeout=20)
        print(f"=== {cmd} ===")
        print(output)

View solution in original post

11 Replies 11

Marcel Zehnder
Spotlight
Spotlight

Can you post the output of the CLI if you send these two commands via a plain SSH-client?

Hi Marcel,

When i run through the command using my code i pasted in my initial query, here is the output i get. it just stops the admin prompt before and executing second command.

 

Hi Marcel,

Please find the output of two commands with plain-ssh client.

Rgds,

Anantha

Marcel Zehnder
Spotlight
Spotlight

Played a little bit with paramiko_expect and had similiar issues - maybe fallback to pure paramiko - see this quick n dirty example as a starting point:

import paramiko
import time

sshsession = paramiko.SSHClient()
sshsession.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sshsession.connect("x.x.x.x", username="xxx", password="xxx")

commands = [
    "show status",
    "utils service restart Engine"
]

for cmd in commands:
    time.sleep(2)
    stdin, stdout, stderr = sshsession.exec_command(cmd)
    while not stdout.channel.exit_status_ready():
        if stdout.channel.recv_ready():
            print(stdout.channel.recv(9999).decode())
                
sshsession.close()

Hi Marcel,

Thanks for your valuable time in helping me with the query. I tried running the script you provided, however it is not fully executing.

 

Hi - yeah, it was a quick shot and I don't have access to a VOS instance. Looks like the session takes some time to load. As another quick hack try to wait a couple of seconds before excec the commands and maybe pause a little longer between the commands:

 

 

import paramiko
import time

sshsession = paramiko.SSHClient()
sshsession.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sshsession.connect("x.x.x.x", username="xxx", password="xxx")

# wait 10 seconds for the session to be ready
time.sleep(10)

commands = [
    "show status",
    "utils service restart Engine"
]

for cmd in commands:
    time.sleep(5)
    stdin, stdout, stderr = sshsession.exec_command(cmd)
    while not stdout.channel.exit_status_ready():
        if stdout.channel.recv_ready():
            print(stdout.channel.recv(9999).decode())
                
sshsession.close()

 

 

dstaudt
Cisco Employee
Cisco Employee

This sample may be helpful: https://github.com/CiscoDevNet/axl-ansible-examples/blob/main/paramiko_test.py

Though I'm not immediately spotting the difference, this works for me...

mradell
Level 1
Level 1

Here is a simple script I use as a base for when I need to run CLI commands in CUCM using Netmiko. When set to Generic as the device_type it doesn't know when the command is done running, so you may need to play with the delay_factor on each command to capture the output from whatever command/commands you're running. Hope it helps.

 

import netmiko
from getpass import getpass
from sys import exit

username = input('Enter username: ')
password = getpass('Enter password: ')

host = 'XXX.XXX.XXX'
    
devices = {
    'device_type': 'generic',
    'host': host,
    'username': username,
    'password': password,
          }
    
conn = netmiko.ConnectHandler(**devices)

command = 'show status'
command2 = 'show network eth0'

print(f'Processing for {host}')

output = conn.send_command(command, expect_string=r'admin:', delay_factor=10)
output2 = conn.send_command(command2, expect_string=r'admin:', delay_factor=10)

conn.disconnect()

with open('Results.txt', 'a') as file:
    file.write(output)
    file.write(output2)
        
input('Complete, press any key to close')

exit(0)

 

Marcel Zehnder
Spotlight
Spotlight

Nice, I think this one solves the issue - I was not aware about the generic device - Played with the linux server device type, but wasn't able to change the initial device prompt. Using the generic device type + send_command with expect_string solves this, thanks @mradell 

Marcel Zehnder
Spotlight
Spotlight

@ananthap based on the reply from @mradell , try this one:

from netmiko import ConnectHandler
import logging
import time

logging.basicConfig(filename='netmiko.log', level=logging.DEBUG)
logger = logging.getLogger("netmiko")

device = {
        "device_type": "generic",
        "ip": "xxx.xxx.xxx.xxx",
        "username": "xxx",
        "password": "xxx"
}

with ConnectHandler(**device) as ssh:
    prompt = r"admin:.*"
    commands = [
        "show status",
        "utils service restart Engine"
    ]

    time.sleep(20)

    for cmd in commands:
        output = ssh.send_command(cmd, expect_string=prompt, read_timeout=20)
        print(f"=== {cmd} ===")
        print(output)

Thank you Marcel, mradell.

Your suggesstions helped and saved my time in solving script issue.