How to execute set of commands after sudo using python script
Question: I am trying to automate deployment process using the python. In deployment I
do "dzdo su - sysid" first and then perform the deployment process. But I am
not able to handle this part in python. I have done similar thing in shell
where I used following piece of code,

    
    
    /bin/bash
    
    psh su - sysid  << EOF
    
    . /users/home/sysid/.bashrc
    
    ./deployment.sh
    
    EOF
    

this handles execution of deployment.sh very well. It does the sudo and then
execute the script with sysid id. I am trying to do similar thing using python
but I am not able to find any alternative to << EOF in python.

I am using subprocess.Popen to execute dzdo part, it does the dzdo, but when I
try to execute next command for e.g. say "ls -l", then this command will not
get executed with the sysid, instead, i had to exit from sysid session and as
soon as i exit, it will execute "ls -l" in my home directory which is of no
use. Can someone please help me on this?

And one more thing, in this case I am not calling any deployment.sh but I will
call commands like cp, rm, mkdir etc.


Answer: The text between `<< EOF` and `EOF` in your shell script example will be
written to the standard input of the `psh` process. So you have to redirect
the standard input of your `Popen` instance and write the data either directly
into the `stdin` file of your instance or use the `communicate()` method:

    
    
    #!/usr/bin/env python
    # coding: utf8
    from __future__ import absolute_import, division, print_function
    from subprocess import Popen, PIPE
    
    SHELL_COMMANDS = r'''\
    . /users/home/sysid/.bashrc
    ./deployment.sh
    '''
    
    
    def main():
        process = Popen(['psh', 'su', '-', 'sysid'], stdin=PIPE)
        process.communicate(SHELL_COMMANDS)
    
    
    if __name__ == '__main__':
        main()
    

If you need the output of the process' stdandard output and/or error then you
need to pipe those too and work with the return value of the `communicate()`
call.

