Is it possible to invoke a login shell with a python subprocess?

Viewed 1067

I can use Popen with a bash script to invoke a non-interactive login shell by using '-l' in the shebang line (#!), e.g.

import subprocess
out, err = subprocess.Popen(['shellscript.sh', 'arg'], env={}).communicate()

with contents of shell script something like

#!/bin/bash -l
command --option $1

However, I'm wondering if it's possible to invoke a non-interactive login shell in a Python subprocess without using an intermediate shell script, e.g.

import subprocess
out, err = subprocess.Popen(['command', '--option', 'arg'], env={}).communicate()  # how to make this a login shell?

My goal is to begin the subprocess with a clean environment and source the login script chain (etc/profile, ~/.bash_profile, etc.), which could be different for various users.

1 Answers

It's possible: simply run bash -l:

=> starting python 
MBP:~ roy$ python3
Python 3.7.5 (default, Nov  1 2019, 02:16:32) 
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

==> Run the relevant code. 
>>> import subprocess
>>> out, err = subprocess.Popen(['bash', '-l'], env={}).communicate() 

==> Getting some message from bash. 
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.

==> do something in the shell. 
MBP:roy roy$ echo "in the shell now" 
in the shell now
MBP:roy roy$ exit
logout

==> left the shell. Back in python 
>>> print("back in python") 
back in python
>>> exit(0) 

==> left python. Now back to the original shell. 
MBP:~ roy$ echo back in the original shell
back in the original shell
MBP:~ roy$ 

To run a non-interactive session, pass -c as an additional argument, and then the command you'd like to execute. For example:

out, err = subprocess.Popen(['bash', '-l', "-c", "echo `ls -l | head -5`"], env={}).communicate() 
                                                  ======================

(the underlined part will be executed by the shell).

Related