一个简单的pexpect用法例子直接su到root

来源:互联网 发布:linux shell awk 编辑:程序博客网 时间:2024/06/06 17:34
When i login to a normal user desktop, and open a terminal, i almost always
will su to root, this action has two steps, type 'su', and type password, I
want to automate every operate that contains more than one, and even two steps.
So i had writeen a that has only one function, su to root in one step.
Then i met a problem, i often need to open a file browser with 'sudo' leading
the 'caja' (mate desktop) command, 'sudo' can only run in a terminal, and the
file browser it opened whill occupy this terminal until i type ctrl+c, but if
i add a & to the tail of the command, i have no way to parse password to sudo
, so i update the code to accept any command but not only 'sudo'.
lets see what the code look like:

#!/usr/bin/python
# coding: utf-8
# Sun Aug  7 00:27:41 EDT 2016

# 它的功能是直接su到root, 不需要输密码, 应确保普通用户可以执行它.
# 密码是写定的.
import sys;
import os;
import subprocess;
import pexpect;
import argparse;

def ooArgParse() :
    OoParser = argparse.ArgumentParser();
    OoParser.add_argument('-c, --command', action = 'store', default = 'su',
        type = str, dest = 'command');
    OoArgs = OoParser.parse_args();
    return {'command': OoArgs.command};
    

def main() :
    if os.getuid() == 0 :
    # 如果已经是root, 不进行任何操作.
        return;
    OoComm = ooArgParse()['command'];
    c = pexpect.spawn(OoComm);
    try :
        c.expect(['.*[pP]assword.*'], timeout = 2);
        c.send('940423\n');
        c.interact();
    except :
        print('no match');
    c.close();

if __name__ == '__main__' :
    main();

lets have an analysis to it. i assume that i already have some base knowledge
of python, i only talk about what i think you wont know.
argparse is a module specializes in pass command line arguments.
pexpect is a module specializes in deal with interactive shell command like
su, ssh.

in function ooArgParse, the first line
# OoParser = argparse.ArgumentParser();
creates a ArgumentParser object, right now you need only know that this is
such a object, dont worry what it is , what it does.
next line:
#OoParser.add_argument('-c, --command', action = 'store', default = 'su',
#        type = str, dest = 'command');
specifies that the program should accept an argument, whoes form is '-c' or
'--command',
the keyword argument of add_argument, 'action', whoes value is 'store',
specifies that there is a value follows '-c',
the keyword argument 'default' specifies that if there is no value follows '-c'
, it is equal that there is a 'su' follows '-c',
the keyword argument 'type' specifies that the value that follows '-c' must be
a string,
the keyword argument 'dest' specifies that this argument is refereced as
'command' in the parser object OoParser, for example, OoArgs.command = 'su';
next line:
# OoArgs = OoParser.parse_args();
store argument info in OoArgs, OoArgs.command is the value you pass into the
program with '-c', for example, if you run
this program -c 'sudo ls'
now OoArgs.command is 'sudo ls'.
next, lets see the main function.
# if os.getuid() == 0
if im already the root user, it will do nothing.
next line:
# OoComm = ooArgParse()['command'];
then OoComm is the command you want to run.
now lets see the 'pexpect' part.
# c = pexpect.spawn(OoComm);
run command OoComm from shell, variable c contain some information,
# try :
#        c.expect(['.*[pP]assword.*'], timeout = 2);
#        c.send('940423\n');
#        c.interact();
#    except :
#        print('no match');
'c.expect', you expect to see a string that contains 'password' or 'Password'
at any position within 2 seconds,
when you see it, you 'type' '940423' and type 'Enter', in normal case, you
will type these, but here it is done by pexpect,
after you 'type' the password, pexpect exit, you have finish run the command.
if you havent see what you want see within the time you will wait, the program
will simply print 'no match'.


0 0
原创粉丝点击