简体   繁体   中英

Running a python script on a remote server with sudo privileges

I got to know about python pexcept package to solve my problem of running python script on remote server as root, using the following code:

import pexpect

# Set the username for ssh connection
username = 'zod1@<remote-server-ip>'

# Take a valid password from the user
Password = input("Enter the login password of %s: " %username)

# Run ssh command using spawn
child = pexpect.spawn('ssh ' + username)

# Wait for the password
child.expect('password:')

# Send the password taken from the user
child.sendline(Password)

# Expected three output
i = child.expect (['Permission denied', 'Terminal type', '[#\$] '])

# i will be 0 if ssh is unable to connect
if i == 0:
    print("Permission denied by host. Unable to login")
    child.kill(0)

# i will be 1 if ssh is able to connect but terminal is not set
elif i == 1:
    print('Connected Successfully.\nTerminal type is not set.')
    child.sendline('vt100')
    child.expect('[#\$]')

# i will be 2 if ssh is able to connect and terminal is set
elif i == 2:
    print('Connected Successfully.')
    prompt = child.after
    print('Shell Command Prompt:', prompt.decode("utf-8"))

till here everything works fine, but I need to execute the next parts of the script(not included here) as root user, for that i'm using:

pwd = input("super user password: ")
child = pexpect.spawn('sudo su')
i = child.expect(['[sudo] password for zod1:']) 
child.sendline(pwd)

which gives:

Traceback (most recent call last):
  File "/Users/ravi3.intern/Desktop/new.py", line 131, in <module>
    i = child.expect(['[sudo] password for zod1:']) 
  File "/opt/homebrew/lib/python3.9/site-packages/pexpect/spawnbase.py", line 343, in expect
    return self.expect_list(compiled_pattern_list,
  File "/opt/homebrew/lib/python3.9/site-packages/pexpect/spawnbase.py", line 372, in expect_list
    return exp.expect_loop(timeout)
  File "/opt/homebrew/lib/python3.9/site-packages/pexpect/expect.py", line 181, in expect_loop
    return self.timeout(e)
  File "/opt/homebrew/lib/python3.9/site-packages/pexpect/expect.py", line 144, in timeout
    raise exc
pexpect.exceptions.TIMEOUT: Timeout exceeded.
<pexpect.pty_spawn.spawn object at 0x100c36f40>
command: /usr/bin/sudo
args: ['/usr/bin/sudo', 'su']
buffer (last 100 chars): b'Password:'
before (last 100 chars): b'Password:'
after: <class 'pexpect.exceptions.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 94531
child_fd: 6
closed: False
timeout: 30
delimiter: <class 'pexpect.exceptions.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 1
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
searcher: searcher_re:
    0: re.compile(b'[sudo] password for zod1:'

which seems to getting stuck on child.expect part. I tested the same thing with 'date' instead of 'sudo su' which seems to be working fine with the above approach. So, can someone please help in debugging the error.. TIA!

Your search term in expect doesn't match the output from pexpect.before , which is before (last 100 chars): b'Password:' . You'll want to change that line to:

i=child.expect('Password:')

As another suggestion to improve your code, you can also search on the timeout so that you handle that exception yourself. For example:

i=child.expect(['Password:',pexpect.TIMEOUT], timeout=5)
if i==0:
    child.sendline(Password)
elif i==1:
    print('Command failed to run, timeout')

The problems in the above script were:

  1. i = child.expect(['[sudo] password for zod1:'])

    Here, [sudo] was not escaped like \[sudo\] hence, pexpect was not able to find match since it expects a pattern.

  2. child = pexpect.spawn('sudo su') spawned a new independent process instead of continuing with the already spawned process. Using child.sendline('sudo su') resolved the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM