子进程Python。。串连命令

子进程Python。。串连命令,python,linux,python-3.x,subprocess,Python,Linux,Python 3.x,Subprocess,我正在编写一个Python程序,需要返回在漏洞扫描中扫描的活动主机。在返回XML之前,我使用过这种方法,但当我尝试附加这些额外的程序(如cut和grep)时,我遇到了一些问题。也许它不喜欢“pipes”|或者我在这里用逗号做了一些完全错误的事情,但我尝试了各种方法,似乎无法让它像从命令行独立运行命令时那样返回结果。非常感谢您提供的任何帮助 def activeHostsQuery(): args = ['curl', '-s', '-k', '-H', 'X-Requested-With

我正在编写一个Python程序,需要返回在漏洞扫描中扫描的活动主机。在返回XML之前,我使用过这种方法,但当我尝试附加这些额外的程序(如cut和grep)时,我遇到了一些问题。也许它不喜欢“pipes”|或者我在这里用逗号做了一些完全错误的事情,但我尝试了各种方法,似乎无法让它像从命令行独立运行命令时那样返回结果。非常感谢您提供的任何帮助

def activeHostsQuery():
    args = ['curl', '-s', '-k', '-H', 'X-Requested-With: curl demoapp', '-u','username:password', 'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv', '|', 'cut', '-d', '-f1', '|', 'sort', '|', 'uniq', '|', 'grep', '-E', '"\"[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\""', '|', 'wc', '-l']

    activeHostsNumber = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
    return activeHostsNumber
我想试试这个:

def activeHostsQuery():
    args = ['curl', '-s', '-k', '-H', 'X-Requested-With: curl demoapp', '-u','username:password', 'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv', '|', 'cut', '-d', '-f1', '|', 'sort', '|', 'uniq', '|', 'grep', '-E', '"\"[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\""', '|', 'wc', '-l']

    activeHostsNumber = subprocess.Popen(" ".join("'%s'" % a for a in args), shell=True, stdout=subprocess.PIPE).communicate()[0]
    return activeHostsNumber
编辑:在参数周围添加引号

另一个编辑:确定,尝试将命令设置为单个字符串:

def activeHostsQuery():
    cmd = 'curl -s -k -H \'X-Requested-With: curl demoapp\' -u username:password \'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv\' | cut -d, -f1 | sort | uniq | grep -E \'"[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}"\' | wc -l'

    ctiveHostsNumber = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE).communicate()[0]
    return activeHostsNumber
我想试试这个:

def activeHostsQuery():
    args = ['curl', '-s', '-k', '-H', 'X-Requested-With: curl demoapp', '-u','username:password', 'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv', '|', 'cut', '-d', '-f1', '|', 'sort', '|', 'uniq', '|', 'grep', '-E', '"\"[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\""', '|', 'wc', '-l']

    activeHostsNumber = subprocess.Popen(" ".join("'%s'" % a for a in args), shell=True, stdout=subprocess.PIPE).communicate()[0]
    return activeHostsNumber
编辑:在参数周围添加引号

另一个编辑:确定,尝试将命令设置为单个字符串:

def activeHostsQuery():
    cmd = 'curl -s -k -H \'X-Requested-With: curl demoapp\' -u username:password \'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv\' | cut -d, -f1 | sort | uniq | grep -E \'"[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}"\' | wc -l'

    ctiveHostsNumber = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE).communicate()[0]
    return activeHostsNumber

我知道这不能回答问题。。。但这是shell脚本。 如果希望shell脚本将参数传递给sh-c(或bash或其他)

或者像其他建议的那样使用
shell=True
。如果你关心这些事情,这在Windows上肯定不起作用

实际上,您可能应该这样做:

import requests
from csv
from StringIO import StringIO
import re

req=reqeusts.get(
    'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv',
    auth=('username','passoword'),
    headers={'X-Requested-With': 'curl demoapp'})

reader = csv.reader(StringIO(req.text))
count = 0
for line in reader:
    if re.match(r'.*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*',line[0]) is not None:
        count += 1

print count

我知道这不能回答问题。。。但这是shell脚本。 如果希望shell脚本将参数传递给sh-c(或bash或其他)

或者像其他建议的那样使用
shell=True
。如果你关心这些事情,这在Windows上肯定不起作用

实际上,您可能应该这样做:

import requests
from csv
from StringIO import StringIO
import re

req=reqeusts.get(
    'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv',
    auth=('username','passoword'),
    headers={'X-Requested-With': 'curl demoapp'})

reader = csv.reader(StringIO(req.text))
count = 0
for line in reader:
    if re.match(r'.*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*',line[0]) is not None:
        count += 1

print count

将命令串在一起的正确方法是创建多个Popen对象,如果您不想使用shell,那么应该这样做

def activeHostsQuery():
    args1 = ['curl', '-s', '-k',
             '-H', 'X-Requested-With: curl demoapp',
             '-u','username:password',
             'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv']
    args2 = ['cut', '-d', '-f1']
    args3 = ['sort', '-u']
    args4 = ['grep', '-E', '"\"[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\""']
    args5 = ['wc', '-l']

    p1 = subprocess.Popen(args1, stdout=subprocess.PIPE)
    p2 = subprocess.Popen(args2, stdin=p1.stdout, stdout=subprocess.PIPE); p1.stdout.close()
    p3 = subprocess.Popen(args3, stdin=p2.stdout, stdout=subprocess.PIPE); p2.stdout.close()
    p4 = subprocess.Popen(args4, stdin=p3.stdout, stdout=subprocess.PIPE); p3.stdout.close()
    p5 = subprocess.Popen(args5, stdin=p4.stdout, stdout=subprocess.PIPE); p4.stdout.close()
    activeHostsNumber = p5.communicate()[0]
    return activeHostsNumber
这样做的好处是不涉及shell——您可以将任意变量替换到参数列表中,而不必担心它们会被字符串分割、误解、导致重定向或其他任何情况,并且在生成列表时使用的参数之间的区别将得到尊重


现在,在这个特殊的例子中,我将使用本机Python来完成整个工作——当您有本机HTTP库时,甚至没有理由使用curl——但是知道如何使用subprocess.Popen构建管道在任何情况下都是有用的。

将命令串在一起的正确方法——如果您不想使用shell,您应该创建多个Popen对象

def activeHostsQuery():
    args1 = ['curl', '-s', '-k',
             '-H', 'X-Requested-With: curl demoapp',
             '-u','username:password',
             'https://qualysapi.qualys.com/api/2.0/fo/scan/?action=fetch&scan_ref=scan/1111111.22222&mode=brief&output_format=csv']
    args2 = ['cut', '-d', '-f1']
    args3 = ['sort', '-u']
    args4 = ['grep', '-E', '"\"[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\""']
    args5 = ['wc', '-l']

    p1 = subprocess.Popen(args1, stdout=subprocess.PIPE)
    p2 = subprocess.Popen(args2, stdin=p1.stdout, stdout=subprocess.PIPE); p1.stdout.close()
    p3 = subprocess.Popen(args3, stdin=p2.stdout, stdout=subprocess.PIPE); p2.stdout.close()
    p4 = subprocess.Popen(args4, stdin=p3.stdout, stdout=subprocess.PIPE); p3.stdout.close()
    p5 = subprocess.Popen(args5, stdin=p4.stdout, stdout=subprocess.PIPE); p4.stdout.close()
    activeHostsNumber = p5.communicate()[0]
    return activeHostsNumber
这样做的好处是不涉及shell——您可以将任意变量替换到参数列表中,而不必担心它们会被字符串分割、误解、导致重定向或其他任何情况,并且在生成列表时使用的参数之间的区别将得到尊重


现在,在这个特殊的例子中,我将使用本机Python来完成整个工作——当您有本机HTTP库时,甚至没有理由使用curl——但是知道如何使用subprocess.Popen构建管道在任何情况下都是有用的。

您尝试过添加“shell=True”吗
subprocess.Popen的参数
?activeHostsNumber=subprocess.Popen(args,stdout=subprocess.PIPE,shell=TRUE)。communicate()[0]。。。。。这给了我一个真正的“全球名称”“未定义错误需要为‘True’,而不是‘True’-大小写。curl:有关详细信息,请尝试‘curl--help’或‘curl--manual’。”。。这就是我在进行这些更改时得到的信息正确的方法是根本不使用任何shell命令。Python可以完成curl、cut、sort、grep和wc为您所做的一切。您是否尝试将“shell=True”参数添加到
subprocess.Popen
?activeHostsNumber=subprocess.Popen(args,stdout=subprocess.PIPE,shell=True)。communicate()[0]。。。。。这给了我一个真正的“全球名称”“未定义错误需要为‘True’,而不是‘True’-大小写。curl:有关详细信息,请尝试‘curl--help’或‘curl--manual’。”。。这就是我在进行这些更改时得到的信息正确的方法是根本不使用任何shell命令。Python可以完成curl、cut、sort、grep和wc为您所做的所有操作。在进行这些调整后,它只返回一个空行,程序停止执行是否可能我没有在args中的正确内容周围添加逗号?我认为您不需要任何逗号。我对我的解决方案做了一个更改,在所有参数周围添加引号,因为您的一些参数中有空格和特殊字符。所以我可以从所有参数中删除所有逗号和单引号?。。我现在正在尝试,但没有太多成功您准备的
args
变量是一个字符串列表。每个字符串必须用引号括起来,并用逗号与下一个字符串隔开。但是您不希望将字符串列表传递给
subprocess.Popen
当您使用
shell=True
参数时,您希望将单个字符串传递给它-这就是为什么我有
“”。join(“%s”%a表示args中的a)
在我的解决方案中。在进行这些调整后,它只返回一个空行,程序停止执行是否可能我没有在参数中的适当位置加逗号?我认为您不需要在任何位置加逗号。我对我的解决方案做了一个更改,在所有参数周围添加引号,因为您的一些参数中有空格和特殊字符。所以我可以从所有参数中删除所有逗号和单引号?。。我现在正在尝试,但没有太多成功您准备的
args
变量是一个字符串列表。每个字符串必须用引号括起来,并用逗号与下一个字符串隔开。但是您不想将字符串列表传递给
subprocess.Popen
当您使用
shell=True
参数时,您想传递一个字符串-这就是为什么我的解决方案中有
“”。join(“%s'%a表示args中的a)
。顺便说一句,我很确定这里给grep的正则表达式是错误的。我没有改变它,因为它是giv