0

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.

1 Answer 1

2

It doesn't work because you have to use CTRL+D to exit sys.stdin.readlines() which closes the stream and further calls to it do nothing (i.e. return empty list).

Sign up to request clarification or add additional context in comments.

1 Comment

Didn't know EOF worked like that, I just assumed it would prompt for another set of input(s). Thank you, sir!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.