我有一个shell脚本叫做“新罕布什尔州“它将本地网络中的ip地址和SSH放入该ip,然后从该ip连续读取一些数据并将结果附加到名为”日志.txt“在服务器上。在
我需要编写一个在服务器上运行的Python代码,它可能使用多线程在一个线程中运行此脚本,然后在另一个线程中读取文件中已有的值。”日志.txt". 我该怎么做?在
我写了以下代码:
#!/usr/bin/python
import threading
import time
from subprocess import call, Popen, PIPE
exitFlag = 0
class loggerThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
print "Logging thread started ..."
def run(self):
with open("log.txt","at") as log:
call(['/bin/sh', 'nn.sh', '172.20.125.44', '10'], stdout = log)
class readerThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
print "Reading thread started ..."
def run(self):
while 1:
with open("log.txt","r") as log:
lines = log.read().split("\n")
print "Reader thread ..."
print lines[-1]
thread1 = loggerThread()
thread2 = readerThread()
thread1.start()
thread2.start()
以下是“的内容”新罕布什尔州“:
^{pr2}$但是,如果我运行此代码,则不会将任何内容存储在“日志.txt". 有什么办法解决这个问题吗?在
进程不必从Python多线程,而是从shell执行。将shell脚本放入一个函数中,并在另一个进程中附加一个与号(&;)来调用它。你找到PID就可以杀死它。然后迭代日志文件,并在写入日志文件时打印任何内容。在
试图通过这样的文件将信息从一个进程(或线程)流到另一个进程(或线程)是个坏主意。你必须让编写器确保在每一行之后刷新文件(而不是在中间行刷新文件),你必须同步,这样你只在有新数据要读取时才读取文件,而不是尽可能快地旋转,你必须弄清楚如何检测何时有新的数据要读取(这是特定于平台的),等等
这正是管道的用途。事实上,考虑到这条线:
…我怀疑您复制并粘贴了一些使用管道执行操作的代码,否则,您为什么要导入
PIPE
?在还有,我不知道你为什么认为你需要两条线。如果必须将输入发送到shell脚本并读取输出,那么使用两个线程可能会更容易。但您所要做的就是启动子进程,并在它可用时读取它的输出。所以只需从主线程的管道中读取。在
文档中有一些例子说明了如何做你想要的。在
^{pr2}$迭代一个管道将会阻塞,直到另一行可用,然后读取整行,只要没有一行的长度超过
select.PIPE_BUF
(保证至少是512)。在如果出于其他原因(例如,当这个线程收集输出时,您需要在主线程中执行一些其他工作),那么您可以使用与Python中任何其他线程完全相同的方法:创建一个
threading.Thread
子类,或者传递一个target
函数。例如:(当然,您可以让它成为一个守护线程,或者想出一种方法来通知它,而不是用无限的超时来连接它等等;如果您知道自己想要什么但不知道如何去做,请阅读一个基本教程或
threading
模块文档,如果您在某个地方卡住了,请另外发布一个新问题。)如果在某些*nix平台上,您可能需要处理长得离谱的行(尽管在最新版本的OS X、FreeBSD、Linux或Solaris上似乎没有必要),那么您可能需要手动循环:
这是@abarnert概念的变体。它运行着“新罕布什尔州“命令,然后按显示的方式处理每行数据。输出被写入
sys.stdout
,然后被刷新,这样我们就可以看到它来了,在结尾处看到它。在来源
相关问题 更多 >
编程相关推荐