【问题标题】:Python 2.6 - passing | char into os.system in for loopPython 2.6 - 通过 |在 for 循环中将字符写入 os.system
【发布时间】:2012-09-12 17:17:56
【问题描述】:

我有一个 IP 列表,我想针对这些 IP 运行 whois(使用 linux 工具 whois)并且只看到 Country 选项。

这是我的脚本:

import os
import time

iplist = open('ips.txt').readlines()

for i in iplist:
        time.sleep(2)
        print "Country: IP {0}".format(i)
        print os.system("whois -h whois.arin.net + {0} | grep Country ".format(i))

所以我想显示正在运行的 IP,然后我只想使用 grep 查看 Country 信息。当我运行它并且 grep 没有运行时,我看到了这个错误:

sh: -c: line 1: syntax error near unexpected token `|'
sh: -c: line 1: ` | grep Country '

下面的代码有效,所以它一定是我的 for 循环的问题:

 print os.system("whois -h whois.arin.net + {0} | grep Country ".format('8.8.8.8'))

我做错了什么?谢谢!!!!

【问题讨论】:

  • 出现错误之前在打印语句中打印了什么? (我猜你得到一个空字符串或像我一样的东西)
  • 我看到输出就好像我运行了这个:'whois -h whois.arin.net + {0}'。它基本上忽略了'| grep 国家/地区'
  • 我找到了一个便宜的解决方法...我可以删除 "| grep Country" 并添加到 "print os.system("echo Country: IP {0}".format( i))”,然后运行像“python whois.py | grep Country”这样的脚本
  • 这部分... print "Country: IP {0}".format(i)

标签: python for-loop os.system


【解决方案1】:

您不会从从文件中读取的行中删除尾随换行符。结果,您将向os.system 传递一个类似"whois -h whois.arin.net + a.b.c.d\n | grep Country" 的字符串。 shell 将字符串解析为两个命令并抱怨“意外的令牌 |”在第二个开头。这就解释了为什么使用"8.8.8.8"之类的手工字符串不会报错。

sleep后加i = i.strip(),问题就消失了。

【讨论】:

  • 谢谢! strip() 方法是否在不向其传递任何参数的情况下从字符串的开头/结尾删除所有特殊字符?还是只有结束?谢谢谢谢谢谢
  • str.strip 返回一个新字符串,其中删除了字符串开头和结尾的所有空格(空格、制表符、\n、\r 等)。这不仅是删除换行符的好主意,而且对于一般的健壮性也是一个好主意 - 您不希望尾随空格破坏您的脚本。
  • 有关strip和rstrip等字符串方法的更多信息,请参阅docs.python.org/library/stdtypes.html#str.strip的文档。
【解决方案2】:

user4815162342 关于您遇到的问题是正确的,但我是否建议您将os.system 替换为subprocess.Popen?捕获system 调用的输出并不直观。如果您希望结果转到屏幕以外的任何地方,您可能会遇到问题

from subprocess import Popen, PIPE

server = 'whois.arin.net'

def find_country(ip):
    proc = Popen(['whois', '-h', server, ip], stdout = PIPE, stderr = PIPE)
    stdout, stderr = proc.communicate()

    if stderr:
        raise Exception("Error with `whois` subprocess: " + stderr)

    for line in stdout.split('\n'):
        if line.startswith('Country:'):
            return line.split(':')[1].strip() # Good place for regex


for ip in [i.strip() for i in open('ips.txt').readlines()]:
    print find_country(ip)

Python 在字符串处理方面非常出色 - 没有理由创建 grep 子进程来模式匹配单独子进程的输出。

【讨论】:

  • 感谢您的评论。幸运的是,我只需要阅读屏幕上的输出,但我很可能需要捕获输出以进行报告。太好了,谢谢!
【解决方案3】:

试试sh:

import os
import time
import re
import sh

iplist = open('ips.txt').readlines()

for i in iplist:
    time.sleep(2)
    print "Country: IP {0}".format(i)
    print sh.grep(sh.whois(i, h="whois.arin.net"), "Country")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 2015-08-12
    • 2013-08-28
    相关资源
    最近更新 更多