Reputation: 273
In linux to set a proxy value you do the following.
proxy=http://$user:$password@proxy.server.com:${NUM}
http_proxy="$proxy" https_proxy="$proxy" ${COMMAND}
For security reasons, if you run this in a subshell, you are not explicitly letting your password in the open, or in the logs. Problem with this approach is, I have to set user name and password everytime I want to run a command.
Therefore decided to write a python code for it. I have a working version in C. Just wanted to learn more in Python. I have found nice ways to encode and decode my password, and after most of the hooplahs, I pass it to this function to test proxy connection.
def test_connection(creds,proxy_url):
import pycurl
import cStringIO
buf = cStringIO.StringIO()
test_url="http://www.google.com"
c = pycurl.Curl()
c.setopt(c.URL, test_url)
c.setopt(c.WRITEFUNCTION, buf.write)
c.setopt(c.PROXY, proxy_url)
c.setopt(c.PROXYPORT, 8080)
c.setopt(c.PROXYTYPE, c.PROXYTYPE_HTTP)
c.setopt(c.PROXYAUTH, c.HTTPAUTH_NTLM)
c.setopt(c.PROXYUSERPWD, creds)
c.perform()
buf.close()
return c.getinfo(c.RESPONSE_CODE)
Where I'm having problems is using suprocess, I do understand that subprocess does not allow you to use export, since it is not really a command. Subprocess module errors with 'export' in python on linux?
this is my implementation
finalCommand = ["/bin/sh", "-c"]
finalCommand.append(http_proxy)
finalCommand.append(https_proxy)
for x in bashCommand:
finalCommand.append(x)
print subprocess.call(finalCommand)
process = subprocess.Popen(finalCommand,stdout=subprocess.PIPE)
out, err = process.communicate()
print "Output ... \n %s" % (out)
if err == None:
print "No errors"
else:
print "Errors ... \n %s" %(err)
Unfortunately, after several tests, my program always return no output and no error. I have printed the output of the curl, so i know the decode, encode, or proxy isn't the issue. Any suggestions?
POST-ANSWER EDIT: Interaction between Python script and linux shell
env did solve my problem, but I also had to refer to the thread above. Some of the commands I ran were interactive one, and as it explains it well in the thread, PIPE doesn't work properly with interactive programs.
Upvotes: 1
Views: 6671
Reputation: 366083
It's hard to be sure without knowing exactly what commands you're trying to run, but I'm pretty sure what you want to do here is just set up the environment for your subprocess, using the env
argument to Popen
:
env = dict(os.environ)
env['http_proxy'] = proxy
env['https_proxy'] = proxy
for command in commands:
out = subprocess.check_output(command, env=env)
If you want to modify your own environment, rather than just the subprocesses' environments, just modify os.environ
in place. (See the documentation for platform-specific issues, and how to deal with them.)
Meanwhile, the reason you're getting no errors is simple:
process = subprocess.Popen(finalCommand,stdout=subprocess.PIPE)
out, err = process.communicate()
If you don't pass stderr=subprocess.PIPE
to the Popen
constructor, it doesn't capture stderr, so err
ends up as None
.
As a side note, you almost never want to check == None
. Often, just if not err:
is sufficient. When it's not, if err is not None:
is almost always required. The set of cases where ==
is necessary but not insufficient is vanishingly small. See the Programming Recommendations in PEP 8 for (slightly) more details.
And one more side note: You can just write finalCommand.extend(x)
. The list.extend
method does the same thing as looping over an iterable and append
ing each element one by one, except that it's more readable, harder to get anything wrong, more concise, and faster.
Upvotes: 5