我的python脚本不会从bash脚本

时间:2016-05-21 00:00:06

标签: python bash matplotlib

我正在开展一个学校项目,我没有太多时间来完成它。我无法找到解决方案。我阅读了大量的参考资料,但我不是开发人员。 以下代码的一半不是来自我,这解释了为什么我找不到解决方案。

我的问题:

我必须在bash(使用日志)中收集来自Iptables的拒绝,并在Python中制作一个非常简单的实时图表。

我已经这样做了:

在bash中

#!/bin/sh
for i in {1..10}
do
  p22=`cat  /var/log/messages | grep 'MONFIREWALL' |grep DPT="22"  | wc -l`
  p80=`cat  /var/log/messages | grep 'MONFIREWALL' |grep DPT="8080"| wc -l`
  p12=`cat  /var/log/messages | grep 'MONFIREWALL' |grep DPT="12" | wc -l`
  p123=`cat  /var/log/messages | grep 'MONFIREWALL' |grep DPT="123" | wc -l`
  p1234=`cat  /var/log/messages | grep 'MONFIREWALL' |grep DPT="1234" | wc -l`
  echo "Le port n°22   a subit " $p22 "attaque(s)" 
  echo "Le port n°80   a subit " $p80 "attaque(s)"
  echo "Le port n°12   a subit " $p12 "attaque(s)"
  echo "Le port n°123  a subit " $p123 "attaque(s)"
  echo "Le port n°1234 a subit " $p1234 "attaque(s)"
  echo "------------ REFRESH -----------"
  sleep 5
done

在Python中:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
import os
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
def animate(i):
    pullData = open("sampleText.txt","r").read()
    dataArray = pullData.split('\n')
    xar = []
    yar = []
    for eachLine in dataArray:
        if len(eachLine)>1:
            x,y = eachLine.split(',')
            xar.append(int(x))
            yar.append(int(y))
    ax1.clear()
    ax1.plot(xar,yar)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

我不知道如何将我的bash变量放在PullData而不是.txt文件中。

我得到了我的变量:

import os
x22=os.environ['p22']

如果有人能帮助我,我会很高兴的。 请原谅我的英文;我是法国人。

2 个答案:

答案 0 :(得分:1)

您的 bash 脚本必须导出变量才能将它们放入主环境空间。从那里,您的Python的 os.environ 调用将能够找到该值。在上一个代码部分中,请尝试打印 x22 以检查其是否有效。

答案 1 :(得分:0)

看看你想要实现的目标,即动态更新的图表,我建议你不能用环境变量来做。您可以从父shell设置和导出它们,但是父级和子级的环境是独立的,因此父级中所做的任何更改都不会在子级中显示。

您可以在Python中实现bash脚本功能,但我认为您必须使用bash脚本。一种方法是让bash脚本写入"拉数据"文件,Python脚本然后读取和绘制,就像它目前一样。此方法会出现问题,因为Python脚本在更新文件时可能会读取文件,从而接收不完整或混合的值。有一些方法可以同步访问,但是,这很麻烦。

更好的方法是从Python中调用 bash脚本。 bash脚本会将数据写入标准输出,Python可以读取并制作图形,而不必担心bash脚本会在处理过程中覆盖它。您可以使用subprocess.check_ouput()(或subprocess.run(),如果使用Python> = 3.5):

bash脚本

#!/bin/sh

PORTS="22 8080 12 123 1234"    
for port in $PORTS
do
    count=$(grep "MONFIREWALL.*DPT=$port" /var/log/messages | wc -l)
    echo "$port,$count"
done

然后在Python脚本中通过更改count_rejects,sh的前几行来调用脚本(假设它名为animate()):

from subprocess import check_output

COUNT_REJECTS = '/path/to/count_rejects.sh'

def animate(i):
    data = check_output([COUNT_REJECTS])
    dataArray = data.split('\n')
    ...

可以对Python代码进行一些其他改进,例如:图表数据应该在绘图之前进行排序,但这应该足以让你前进。

您可能想要使用条形图而不是图形。