4

I am writing a python script to log into (not ssh/telnet) a remote system (not a Linux) and run commands. Below is an example that does the things manually.

root@centos (Centos 7.3) ➜  ~ shell_tool --cmd "<cmd1>;<cmd2>" 
//interactive shell
System address: 10.0.0.1
Username: admin
Password: 123456

<output>

Besides to login and run commands, I also want to save the output. shell_tool --cmd ";" >>output.txt does not work here because there is interactive shell after the command.

Can someone help with the script?

3
  • Have a look at pxssh in pexpect. Commented Jul 25, 2019 at 5:38
  • It's not a ssh connection, it's a private shell tool. I want the user to input the system address, username and password, pexpect seems to not help here. Commented Jul 25, 2019 at 5:48
  • You can use getpass to read a password without showing the letters typed. You can use pexpect to drive any command line utility. Commented Jul 25, 2019 at 5:53

1 Answer 1

3

We can create mockup.py that will be a stand-in for whatever program you are trying to control:

import getpass

hostname = input('System address: ')
username = input('Username: ')
password = getpass.getpass('Password: ')
if password == 'good_guess':
    while True:
        line = input('mockup> ')
        if line == 'quit':
            break

Sample Interaction

$python mockup.py
System address: bogus
Username: nobody
Password: 
mockup> fake command
mockup> quit

We can write a Python program that will control mockup.py and log all interaction to a file named session.log:

import pexpect
import getpass

hostname = input('hostname: ')
username = input('username: ')
password = getpass.getpass('password: ')
prompt = 'mockup> '

with open('session.log', 'wb') as log_file:
    session = pexpect.spawn('python3 mockup.py')
    session.expect_exact('System address: ')
    session.sendline(hostname)
    session.expect_exact('Username: ')
    session.sendline(username)
    session.expect_exact('Password: ')
    session.sendline(password)
    # Start logging to a file here
    session.logfile_read = log_file
    session.expect_exact(prompt)
    session.sendline('fake command')
    session.expect_exact(prompt)
    session.sendline('quit')
    session.expect_exact(pexpect.EOF)

Sample Interaction

$ python3 use_pexpect.py 
hostname: bogus
username: nobody
password: 

Contents of session.log

mockup> fake command
mockup> quit

This should be enough information to get you started.

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

4 Comments

Thank you! Is there anyway to hide the plaintext of password in session.log? Or totally remove the login process in session.log, only show the output of commands.
@Chris.Zhou I changed the solution so that it starts logging after the login interaction is complete. Also, I changed the logging to use logfile_read so that only the data received from the program is logged. If you want to continue to log everything, use session.logfile = log_file.
@David.Cullen Don't know why the script doesn't work well on my side. Issue is regarding "session.expect_exact(prompt)". I also added it in my script session.expect(‘*>’), it doesn’t work as well. The prompt in my system is like “username@hostname>” When I removed two "session.expect_exact(prompt)” and “session.sendline('quit’)”, the script works well.
Hopefully it is obvious that you did not provide enough information for me to create a mockup.py that duplicated your environment. Also, my answer was designed to give you a starting point for you to adapt to your specific problem. At the minimum, you would have to change prompt = 'mockup> ' to reflect your specific situation.

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.