I'm writing a script (Python 2.7.10) to log in to networking devices and gather diagnostics information that the vendor can potentially ask for. It's fairly straightforward, but I've run into an interesting problem (at least for me).
I've exhausted my limited knowledge on this.
This is the piece of the code that calls the functions to run:
elif args.hostname and args.username and args.jtac and args.commands and args.shell:
print("RUN FOR SINGLE HOST w/ SHELL AND CLI COMMANDS")
open_ssh_session(args.hostname, args.username, password)
commands_and_iterations_cli(args.hostname, args.jtac, args.iterations, float(args.interval))
commands_and_iterations_shell(args.username, args.hostname, args.jtac, args.iterations, float(args.interval))
single_core_dump(args.hostname, args.username, password, args.jtac)
pull_files_from_juniper_device(args.hostname, args.username, password, args.jtac)
push_files_to_juniper_sftp(args.hostname, args.username, password, args.jtac)
So I have 2 functions:
def commands_and_iterations_cli(hostname, jtac, iterations, interval):
print("Enter each JUNOS CLI command on separate lines, press CTRL+D when finished.\n"
"NOTE: Valid CLI commands only, DO NOT input shell commands here!\n")
# Take user input, enter a command on each new line, send EOF to indicate that you're done.
cli_commands = sys.stdin.readlines()
# Instantiate user shell.
channel = client.invoke_shell()
# Take each line from given input, and iterate over hostname.
for line in cli_commands:
line = line.strip()
iter_counter = 0
print("Running {}, {} times, every {} seconds.".format(line, str(iterations), interval))
while iter_counter < iterations:
iter_counter = iter_counter + 1
channel.send(line +' | save "{}-{}-{}"\n'.format(hostname, jtac, line))
time.sleep(interval)
def commands_and_iterations_shell(username, hostname, jtac, iterations, interval):
print("Enter each shell command on separate lines, press CTRL+D when finished.\n"
"NOTE: Valid shell commands only, DO NOT input JUNOS CLI commands here!\n"
"** ENSURE COMMANDS ARE SAFE TO RUN IN PRODUCTION IF DOING SO! **\n")
# Take user input, enter a command on each new line, send EOF to indicate that you're done.
shell_commands = sys.stdin.readlines()
# Prompt for hostname's root password to enter root shell.
print("Enter root password for {}:\n".format(hostname))
rootpass = getpass.getpass()
# Instantiate user shell.
channel = client.invoke_shell()
# Start root shell.
channel.send("start shell user root\n")
# Let the prompt become available.
time.sleep(1)
# Send the password and let the root prompt return.
channel.send(rootpass+"\n")
time.sleep(1)
# Take each line from given input, and iterate over hostname.
for line in shell_commands:
line = line.strip()
print("Running {}, {} times, every {} seconds.".format(line, str(iterations), interval))
iter_counter = 0
while iter_counter != iterations:
channel.send(line +' >> "/var/home/{}/{}-{}-{}" \n'.format(username, hostname, jtac, line))
time.sleep(interval)
iter_counter = iter_counter + 1
print(iter_counter)
The code runs perfectly if I run commands_and_iterations_cli() or commands_and_iterations_shell() independently. However when I try both (the example given), the CLI function will run correctly, then when it comes time to run the shell function, the shell function will print the text in it, and prompt for the root password, and then immediately skip to the next function after it without prompting for commands. I've even tried giving it a 30 second sleep before the shell function runs, and the behavior just follows.
Thanks, all.