Python:如果找到字符串,如何扫描子流程的stderr或stdout并执行操作?

Python:如果找到字符串,如何扫描子流程的stderr或stdout并执行操作?,python,linux,python-2.7,Python,Linux,Python 2.7,下面的代码在3/3之后无法退出,即使我的linux终端中弹出的stderr text[ERROR]ssh目标不支持密码验证。我相信文本是stderr输出,因为Hydra的源代码中有以下行: hydra模块ssh.c源代码剪贴画: fprintfstderr,[ERROR]ssh目标 我的程序似乎没有正确地扫描stderr以查找字符串。变量输出应该捕获这个输出,然后我想对[ERROR]字符串的出现进行grep。如果发现了,我希望程序退出,而不是对一个无懈可击的服务运行20k次登录尝试 感谢您的帮助

下面的代码在3/3之后无法退出,即使我的linux终端中弹出的stderr text[ERROR]ssh目标不支持密码验证。我相信文本是stderr输出,因为Hydra的源代码中有以下行:

hydra模块ssh.c源代码剪贴画: fprintfstderr,[ERROR]ssh目标

我的程序似乎没有正确地扫描stderr以查找字符串。变量输出应该捕获这个输出,然后我想对[ERROR]字符串的出现进行grep。如果发现了,我希望程序退出,而不是对一个无懈可击的服务运行20k次登录尝试

感谢您的帮助

我的代码


这不会捕获stderr的结果

因为stderr没有重定向,只有stdout,所以您的程序将无法读取它。您有两种选择:将stderr和stdout混合到一个流中,或者分别捕获它们

如果要将stderr和stdout合并到一个流中

results_Test = subprocess.Popen(
    HYDRA_TEST_COMMAND,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    shell=True)
如果你想要分开的溪流

results_Test = subprocess.Popen(
    HYDRA_TEST_COMMAND,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    shell=True)
使用shell=False 通常不建议使用shell=True,因为它可能导致潜在的意外行为或攻击向量。或者,您可以将参数作为列表而不是字符串传递,然后可以使用默认的更安全、更快的shell=False

如果端口是int,则需要改用strport

在某些情况下,shell=True更方便,但在实践中很少出现

这可能不会影响程序的工作方式,但它消除了文件名中引用或奇怪字符的问题。如果您不喜欢它的冗长程度,可以使用.split将其缩短一点

使用,交流 使用proc.communicate代替proc.stdout.read

如果对stdout和stderr都使用管道,则这将在单独的变量中提供这两个变量的内容。如果改用.stdout.read,进程可能会在等待您从.stderr.read读取时被阻塞。这是.communicate的主要工作-它同时从stderr和stdout读取数据,因此进程不会阻塞

如果使用stderr=subprocess.STDOUT,则stderr将为None,因为内容混合到STDOUT中

在任何一种情况下,建议使用.communicate

results_Test = subprocess.Popen(
    HYDRA_TEST_COMMAND,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    shell=True)
results_Test = subprocess.Popen(
    HYDRA_TEST_COMMAND,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    shell=True)
HYDRA_TEST_COMMAND = [
    'hydra', '-l', 'test', '-p', 'test', '-f',
    '-o', '/var/www/html/recon_scan/results/labs/%s_test.txt' % ip_address,
    '-u', ip_address, '-s', port, 'ssh']
# instead of results_Test.stdout.read()
stdout, stderr = results_Test.communicate()