I am writing a bootstrap code for one of my programs, and trying to install to my virtualenv directory using subprocess.call
initially I used :
subprocess.call(['pip', 'install', '-E', dir_name, 'processing'])
When re-running on ubuntu I noticed that the -E was outdated (http://pypi.python.org/pypi/pip/) and need to use:
virtualenv dir_name && dir_name/bin/pip install processing
This works fine from the cmd line but will not work in subprocess:
subprocess.call(['virtualenv', dir_name, '&&', '{0}/bin/pip'.format(dir_name), 'install', 'processing'])
Returns this error message:
There must be only one argument: DEST_DIR (you gave dir_name && dir_name/bin/pip install processing)
Usage: virtualenv [OPTIONS] DEST_DIR
I have also tried virtualenv.create_bootstrap_script(extra_text) (but can not figure it out and have some additional scripts I am running that are from git)
Wondering what I am doing wrong in subprocess or what I can change.
Thanks!
1 Answer 1
Just check the status of the first command, then conditionally run the second:
retval = subprocess.call(
['virtualenv', dir_name]
)
if retval == 0:
# a 0 return code indicates success
retval = subprocess.call(
['{0}/bin/pip'.format(dir_name), 'install', 'processing']
)
if retval == 0:
print "ERROR: Failed to install package 'processing'"
else:
print "ERROR: Failed to created virtualenv properly."
Warning: danger below!
In order for the && token to work, you must use the argument shell=True in subprocess.call. However, you MUST NOT use shell=True if you're accepting input from the user, because it will then allow arbitrary code execution.
Additionally, you need to join the args together.
If you're using a dir_name that you are hard coding:
cmdline = ' '.join(['virtualenv', dir_name, '&&', '{0}/bin/pip'.format(dir_name), 'install', 'processing'])
subprocess.call(
cmdline,
shell=True
)