django 调用 shell 脚本,日志实时返回问题

2017-04-07 18:19:52 +08:00
 fanne

代码内容:

from subprocess import PIPE,Popen,STDOUT
@celery_app.task
def call_shell(ipList,add_ipList,shell_log,shell_dir,shell_file):
    os.popen(r"echo %s >> %s" % (ipList, add_ipList))
    # output = os.popen("cd %s;/bin/sh %s" % (shell_dir, shell_file))
    p = Popen("cd %s;/bin/sh %s" % (shell_dir, shell_file),stdout=PIPE,stderr=STDOUT,shell=True)
    for line in iter(p.stdout.readline,""):
        shell_log.write(line)
        shell_log.flush()
    shell_log.close()
    os.popen(r"/bin/sed -i '$d' %s" % add_ipList)

在这里我用了 subprocess.Popen 去执行一个 shell 脚本,然后 shell 执行的时候会有一大串内容输出,我直接用了p.stdout.readline读取它到一个 txt 文件中,这个文件我弄成了一个 url 去访问他: http://192.168.1.21/shell_log.txt

最后的问题在于,只有当 shell 内容全部读取后,我才能在页面刷新出内容的。

有没有什么办法, shell 输出一点,我就能在 http://192.168.1.21/shell_log.txt 访问到一点的。

就是有点类似需要实时的看到 shell 日志输出的。而不是当整个 shell 输出完, p.stdout.readline 全部读取完后才能在页面看到的。

6678 次点击
所在节点    Django
10 条回复
0asis
2017-04-07 18:23:37 +08:00
之前做过用 redis 存放内容然后 view 从 redis 里边取
okletswin
2017-04-07 19:32:02 +08:00
class RunningProcess(object):

def __init__(self, process):
self.process = process

def is_running(self):
return bool(self.process.poll() is None)

def readline(self):
line = self.process.stdout.readline()
return line

@property
def unread_lines(self):
lines = self.process.stdout.readlines()
self.process.stdout.close()
return lines

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, universal_newlines=True)

rp = RunningProcess(p)

while rp.is_running():
line = rp.readline()
print(line)

for line in p.unread_lines:
print(line)
okletswin
2017-04-07 19:33:44 +08:00
额,不知道怎么格式化,将就看吧。。。
fanne
2017-04-07 19:40:42 +08:00
@okletswin 回复貌似也是可以用 markdown 语法
```python
class RunningProcess(object):

def __init__(self, process):
self.process = process

def is_running(self):
return bool(self.process.poll() is None)

def readline(self):
line = self.process.stdout.readline()
return line

@property
def unread_lines(self):
lines = self.process.stdout.readlines()
self.process.stdout.close()
return lines
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, universal_newlines=True)
rp = RunningProcess(p)
while rp.is_running():
line = rp.readline()
print(line)
for line in p.unread_lines:
print(line)
```
这样的么
fanne
2017-04-07 19:41:06 +08:00
额,好像也不行。
fanne
2017-04-08 11:26:18 +08:00
稍微给了一点,按照这样就可以了,一边读取日志,未读取完,刷新页面也可以看到日志信息了。
@celery_app.task
def call_shell(ipList_item):
add_ipList = '/qzdata1/ansible_ops/shellDir/ipList'
shell_dir = '/qzdata1/ansible_ops/shellDir'
shell_file = 'v3_addServer.sh'
nowTime = time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime(time.time()))
shell_log = 'static/searchlog/add_game_log_%s.txt' %nowTime
myfile = open(shell_log,"w",0)
os.popen("echo %s >> %s" %(ipList_item,add_ipList))
p = Popen("cd %s && /bin/sh %s" %(shell_dir,shell_file),stdout=PIPE,stderr=STDOUT,shell=True)
for line in iter(p.stdout.readline,""):
myfile.write(line)
myfile.close()
os.popen(r"/bin/sed -i '$d' %s" %add_ipList)
Wellido
2017-04-13 08:28:50 +08:00
请问博主是调用本地的 shell 脚本吗?
fanne
2017-04-13 09:47:20 +08:00
@Wellido 嗯,是的。
kba977
2017-04-13 15:34:44 +08:00
楼主你好,请问可以给我你的邮箱或者微信么,我也有类似的需求,卡了一段时间了。想请教一下。
fanne
2017-04-13 17:22:58 +08:00
@kba977 QQ:896661380

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/353291

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX