首先,我不知道Python的第一件事.所以我真的可以用你的任何指点。我确实知道一些Perl、Bash脚本和一些C++。
我正在运行DenyHosts (http://denyhosts.sourceforge.net/),它不时地通过电子邮件向我发送一条消息,即IP地址添加到/etc/deny.host。例如:
Added the following hosts to /etc/hosts.deny:
87.215.133.109 (unknown)
----------------------------------------------------------------------到目前为止还不错,但是我想在这条消息中加上IP地址的国家。为此,我创建了一个小型Perl脚本,用于输出国家:
/usr/local/bin/geo-ip.pl --short 87.215.133.109
Netherlands所以我要做的就是从Python调用这个Perl脚本,然后在消息字符串中填充结果。我找到了我怀疑需要修改的源代码,但正如消息顶部所宣布的,我不知道Python的第一件事。
这是在report.py中调用子例程的主程序的一个片段。
deny_hosts.py:
#print deny_hosts
new_denied_hosts, status = self.update_hosts_deny(deny_hosts)
if new_denied_hosts:
if not status:
msg = "WARNING: Could not add the following hosts to %s" % self.__prefs.get('HOSTS_DENY')
else:
msg = "Added the following hosts to %s" % self.__prefs.get('HOSTS_DENY')
self.__report.add_section(msg, new_denied_hosts)
if self.__sync_server: self.sync_add_hosts(new_denied_hosts)
plugin_deny = self.__prefs.get('PLUGIN_DENY')
if plugin_deny: plugin.execute(plugin_deny, new_denied_hosts)我觉得这个零钱应该在这里找个地方。report.py定义了add_section:
def add_section(self, message, iterable):
self.report += "%s:\n\n" % message
for i in iterable:
if type(i) in (TupleType, ListType):
extra = ": %d\n" % i[1]
i = i[0]
else:
extra = ""
if self.hostname_lookup:
hostname = self.get_hostname(i)
debug("get_host: %s", hostname)
else: hostname = i
self.report += "%s%s\n" % (hostname, extra)
if self.use_syslog:
syslog.syslog("%s - %s%s" %(message, hostname, extra))
self.report += "\n" + "-" * 70 + "\n"请帮助我更改代码,这样它就会发出如下消息:
Added the following hosts to /etc/hosts.deny:
87.215.133.109 (Netherlands, unknown)
----------------------------------------------------------------------EDIT3:,这就是我解决它的方法。输出与原始消息相同。更改源后,需要重新启动守护进程(sudo /etc/init.d/denyhost重新启动)
def add_section(self, message, iterable):
# added geo-ip
# moving this from statement to the top of the file makes pycheck generate
# a lot of errors, so I left it here.
from subprocess import Popen, PIPE
# end geo-ip hack import
self.report += "%s:\n\n" % message
for i in iterable:
if type(i) in (TupleType, ListType):
extra = ": %d\n" % i[1]
i = i[0]
else:
extra = ""
if self.hostname_lookup:
hostname = self.get_hostname(i)
debug("get_host: %s", hostname)
else: hostname = i
# self.report += "%s%s\n" % (hostname, extra)
# JPH: added geo-ip
geocmd = "/usr/local/bin/geo-ip.pl --short %s" % i
country = Popen( geocmd, shell=True, stdout=PIPE).communicate()[0]
country = country.strip()
self.report += "%s%s\n%s\n" % (hostname, extra, country)
# end geo-ip hack
if self.use_syslog:
syslog.syslog("%s - %s%s" %(message, hostname, extra))
self.report += "\n" + "-" * 70 + "\n"还可以帮助我理解我改变了什么,这样我今天也可以学到一些Python。
EDIT2:为了共享到geo-ip.pl脚本http://wirespeed.xs4all.nl/mediawiki/index.php/Geo-ip.pl的链接
EDIT1:重新编译是在源代码更改时自动完成的,从而回答了下面的问题。第二个问题是,我在系统中找到了两个匹配的文件:
其中.py是源代码,我怀疑.pyc实际上正在执行。因此,当我更改源代码时,如果以后不以某种方式编译它,我不会感到惊讶。
发布于 2012-03-21 08:27:51
我将只回答您问题的具体部分,即如何通过python调用您的perl脚本并获得输出。这个信息的位置太模糊了,我从你的片段里猜不出来……
from subprocess import Popen, PIPE
hostIP = "87.215.133.109"
cmd = "/usr/local/bin/geo-ip.pl --short %s" % hostIP
output = Popen(cmd, shell=True, stdout=PIPE).communicate()[0]
## alternate form ##
# cmd = ["/usr/local/bin/geo-ip.pl, "--short", hostIP]
# output = Popen(cmd, stdout=PIPE).communicate()[0]
print output.strip()
# Netherlands更新
由于我同时在Popen行上做了一些事情,而且您对python (基于下面的评论)是新手,所以我想为您细分一下这一行.
# this call to Popen actually returns a
# Popen object with a number of methods and attributes
# to interact with the process that was just created
p = Popen(cmd, shell=True, stdout=PIPE)
# communicate() is a method of a Popen object which
# allows you to wait for the return output of the pipes
# that you named (or send data to stdin)
# It blocks until data is ready and returns a tuple (stdout, stderr)
stdout, stderr = p.communicate()
# We only wanted the stdout in this case, so we took the first index
output = p.communicate()[0]
# output is a string, and strings have the strip() method to remove
# surrounding whitespace
stripped_output = output.strip()发布于 2012-03-21 08:28:42
这可能会起作用:
import subprocess
country = subprocess.check_output(
["/usr/local/bin/geo-ip.pl", "--short", "87.215.133.109"])https://stackoverflow.com/questions/9800833
复制相似问题