【问题标题】:how to set proxy value and run linux command in python如何在python中设置代理值并运行linux命令
【发布时间】:2014-09-15 04:47:54
【问题描述】:

在 linux 中设置代理值,您可以执行以下操作。

proxy=http://$user:$password@proxy.server.com:${NUM}
http_proxy="$proxy" https_proxy="$proxy" ${COMMAND}

出于安全原因,如果您在子shell 中运行此程序,您并没有明确地让您的密码公开或记录在日志中。这种方法的问题是,每次我想运行命令时都必须设置用户名和密码。

因此决定为它编写一个python代码。我有一个 C 的工作版本。只是想在 Python 中学习更多。我找到了很好的方法来编码和解码我的密码,并且在大多数喧嚣之后,我将它传递给这个函数来测试代理连接。

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)

我在使用 suprocess 时遇到问题,我明白 subprocess 不允许您使用导出,因为它不是真正的命令。 Subprocess module errors with 'export' in python on linux?

这是我的实现

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)

不幸的是,经过几次测试,我的程序总是不返回任何输出,也没有错误。 我已经打印了 curl 的输出,所以我知道解码、编码或代理不是问题。有什么建议?

回答后编辑: Interaction between Python script and linux shell

env 确实解决了我的问题,但我也不得不参考上面的线程。我运行的一些命令是交互式的,正如它在线程中很好地解释的那样,PIPE 不能在交互式程序中正常工作。

【问题讨论】:

  • 您只是在寻找Popenenv 参数吗?还是您实际上是在尝试启动一个 shell 并直接在其中而不是在子 shell 中运行脚本,或者其他时髦的东西?
  • 同时,请给我们一个MCVE——特别注意“完整”部分。在不知道http_proxyhttps_proxybashCommand 中的内容的情况下,很难调试可能出现的问题。 (另外,您是否有原因首先对命令执行 call,然后使用完全相同的命令创建 Popen 并在其上调用 communicate?)
  • “PIPE 不能在交互式程序中正常工作”并不是那么严重(尽管在 Python 3.2 之前确实如此,但您可能不会遇到这种情况,如果遇到这种情况,请安装 @ 987654336@ backport 来解决这个问题),这是一些交互式程序要求您更改缓冲,而其他程序根本不与标准输入对话(例如,他们正在读取密码而不回显它并且需要一个真正的 tty,或者他们只需让 libpam 为他们做这件事,等等),所以管道到标准输入没有任何好处。而且,编写代码以通过管道进行交互而不阻塞也很困难。

标签: python linux shell curl proxy


【解决方案1】:

如果不确切知道您要运行哪些命令,很难确定,但我很确定您在这里要做的只是为您的子进程设置环境,使用 env 参数987654321@:

env = dict(os.environ)
env['http_proxy'] = proxy
env['https_proxy'] = proxy
for command in commands:
    out = subprocess.check_output(command, env=env)

如果您想修改自己的环境,而不仅仅是子进程的环境,只需在原地修改os.environ。 (有关特定于平台的问题以及如何处理这些问题,请参阅文档。)


同时,您没有收到错误的原因很简单:

process = subprocess.Popen(finalCommand,stdout=subprocess.PIPE)
out, err = process.communicate()

如果您不将stderr=subprocess.PIPE 传递给Popen 构造函数,则它不会捕获stderr,因此err 最终会成为None

附带说明一下,您几乎从不想检查== None。通常,只需if not err: 就足够了。如果不是,if err is not None: 几乎总是需要的。 == 是必要的但并非不足的情况非常少。请参阅 PEP 8 中的 Programming Recommendations 了解(稍微)更多详细信息。

还有一个旁注:你可以写finalCommand.extend(x)list.extend 方法与循环遍历一个可迭代对象和 append 逐个元素执行相同的操作,只是它更具可读性、更难出错、更简洁、更快。

【讨论】:

  • 感谢您的提示..我必须自己挖掘这个,但是设置一个环境变量,不会显示在命令行的环境变量中..
  • @kmassada:我不确定你的问题是什么意思。如果一个子进程(比如你的 Python 脚本)修改了它的环境,或者用不同的环境启动了它自己的子进程,这不会影响父 shell,更不用说你正在运行的任何其他 shell。但是,如果您使用subprocess.call(['/bin/sh'], env=env) 或其他方式启动shell,那么是的,env 中的键都将显示为您启动的shell 的变量。
  • 如果你正在使用nodejs puppeteer,如果需要,不要忘记添加env[no_proxy]=somehost
猜你喜欢
  • 1970-01-01
  • 2015-06-03
  • 2017-01-29
  • 1970-01-01
  • 2016-01-03
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多