如何使用subprocess.check_output查找行?

2024-03-29 13:37:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个套接字连接,客户端在那里提交他们的Windows用户名。然后服务器运行'net user username/domain'来查找它们的过期日期。 我试图找到字符串“Password expires”并打印该行。在

print(line)

什么也没给我。 如果我使用

^{pr2}$

我确实得到了命令的全部结果,但它看起来有点混乱。 我怎样才能得到“密码过期”这一行?我是否需要以某种方式格式化它,这样“结果”看起来就不会一团糟?在

    import subprocess

    import os
    from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
    import sys

    PORT_NUMBER = 3555
    SIZE = 1024

    hostName = gethostbyname( '0.0.0.0' )

    mySocket = socket( AF_INET, SOCK_DGRAM )
    mySocket.bind( (hostName, PORT_NUMBER) )

    print ("Test server listening on port {0}\n".format(PORT_NUMBER))

    # Receive no more than 1024 bytes


    while True:
        (data,addr) = mySocket.recvfrom(SIZE)
        try:
            #print >>sys.stderr, 'Received data from', addr
            while True:
                print (data.decode())
                batcmd=('net user ' + data.decode() + ' /domain')
                result = subprocess.check_output(batcmd, shell=True)
                # print (result)  shows details but it is messy looking
                for line in result:
                    if str(line).startswith("Password expires"):
                        print (line)

    #                      if data:
    #                          print >>sys.stderr, 'sending data back to the client'
    #                          mySocket.sendto({ },addr).format(line)
    #                          # TypeError: sendto() argument 1 must be string or buffer, not dict
    #                      else:
    #                          print >>sys.stderr, 'no more data from', client_address
    #                          break

                break

            # send result back to client ?
            #mySocket.send(result.encode('ascii'))
            sys.exit()
        finally:
            print('closing socket')
            mySocket.close()

如果我打印(结果),一切都是这样的:

.local.\r\n\r\nUser Name           js83838\r\nFull Name
    John Doe       \r\n\Country Code       Comment Here.
        Account active      Locked\r\nAccount expires
            more data like this
                and this

更新

我尝试这个,它显示每一行,而不是1。每一行前面都有一个b'字,看起来排列得很好。在

while True:
    (data,addr) = mySocket.recvfrom(SIZE)

    #print >>sys.stderr, 'Received data from', addr
    while True:
        print (data.decode())
        batcmd=('net user ' + data.decode() + ' /domain')
        result = subprocess.check_output(batcmd, shell=True)
        # print (result)  # shows details but it is messy looking
        for line in result.splitlines():
            if str(line).find("Password expires"):
                print (line)

Tags: fromimporttruedatastderrsyslinesocket
2条回答

subprocess.check_output不返回行,而是返回字节缓冲区。在

在将其解码为字符串(Python3中是必需的)之后:

result = result.decode("ascii",errors="ignore")

您需要根据行进行拆分,否则循环将生成一个又一个字符,并且startswith不会崩溃,但什么也找不到。在

^{pr2}$

就这样。所以有两个问题:用startswith检查整个缓冲区,而不解码到{},这使得搜索什么也找不到。在

或者,不要decode,而要if line.startswith(b"Password expires"):。这使代码与Python2兼容,这是额外的好处。在

旁白:解析net user的输出时要小心,因为字符串本地化可能会使程序错过信息。在

这里有一个解决方案,它允许您:逐行获取输出,只获取带有“Password expires”的行,而不使用shell=True。在

batcmd=['net', 'user', data.decode(), '/domain')
net_process = subprocess.Popen(batcmd, stdout=subprocess.PIPE)
grep_process= subprocess.Popen(["findstr", "Password expires"], stdin=net_process.stdout, stdout=subprocess.PIPE)  # or grep depending on your system
for line in grep_process.stdout.readlines():
    # do what you want

相关问题 更多 >