我想从一个长期运行的进程中捕获stdout,subprocess.Popen(...)因此我将其stdout=PIPE用作arg.
但是,因为它是一个长时间运行的进程,我还想将输出发送到控制台(好像我没有管道它)给脚本用户一个它仍在工作的想法.
这是可能吗?
干杯.
我是python的新手,多年来一直使用perl.我一直做的典型事情是perl打开一个命令作为管道并将其输出分配给局部变量进行处理.换一种说法:
"open CMD, "$command|";
$output=<CMD>;
Run Code Online (Sandbox Code Playgroud)
一块蛋糕.我想我可以这样在python中做类似的事情:
args=[command, args...]
process=subprocess.Popen(args, stdout=subprocess.PIPE)
output=process.communicate()
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.现在提出一个大问题......
如果我在多个平台上使用ssh启动该命令,我可以在select循环中监视perl中的描述符,以便在它们进入时处理结果.我确实找到了python select和poll模块,但我不太确定如何使用它们.文档说poll将采用文件句柄,但是当我尝试将上面的变量'process'传递给poll.register()时,我得到一个错误,它必须是int或者有一个fileno()方法.由于Popen()使用了stdout,我试着调用
poll.register(process.stdout)
Run Code Online (Sandbox Code Playgroud)
它不再抛出错误,而只是挂起.
有关如何制作此类作品的任何建议/指示?
我正在尝试实时解析块缓冲程序的输出,这意味着直到进程结束才可用。我需要的只是逐行解析,过滤和管理输出中的数据,因为它可能要运行数小时。
我试图用subprocess.Popen()捕获输出,但是是的,正如您可能猜到的那样,Popen无法管理这种行为,它会一直缓冲直到过程结束。
from subprocess import Popen, PIPE
p = Popen("my noisy stuff ", shell=True, stdout=PIPE, stderr=PIPE)
for line in p.stdout.readlines():
#parsing text and getting data
Run Code Online (Sandbox Code Playgroud)
因此,我发现了pexpect,它可以实时输出输出,因为它将stdout视为文件,或者我什至可以做一个肮脏的技巧来打印文件并在函数外部解析它。但是好吧,即使对于我来说,它也太脏了;)
import pexpect
import sys
pexpect.run("my noisy stuff", logfile=sys.stdout)
Run Code Online (Sandbox Code Playgroud)
但我想这应该是一种更好的pythonic方式,只需像子进程一样管理stdout。普朋呢。我怎样才能做到这一点?
编辑:
运行JF提案:
这是故意的错误审核,大约需要25秒。停止。
from subprocess import Popen, PIPE
command = "bully mon0 -e ESSID -c 8 -b aa:bb:cc:dd:ee:00 -v 2"
p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
for line in iter(p.stdout.readline, b''):
print "inside loop"
print line
print "outside loop"
p.stdout.close()
p.wait()
#$ sudo python SCRIPT.py …Run Code Online (Sandbox Code Playgroud) 如果可能的话,我正在寻找更好的方法来做到这一点:
import subprocess
f = open('temp.file', 'w+')
f.write('hello world')
f.close()
out = subprocess.check_output(['cat', 'temp.file'])
print out
subprocess.check_output(['rm', 'temp.file'])
Run Code Online (Sandbox Code Playgroud)
在此示例中,我正在创建一个文件并将其作为输入传递给cat(实际上不是cat我正在运行,而是解析输入文件的其他程序pcap)。
我想知道的是,在 Python 中是否有一种方法可以创建一个包含某些内容的“类文件对象”,并将这个类文件对象通过管道作为命令行程序的输入。如果可能的话,我认为这比将文件写入磁盘然后删除该文件更有效。
有两个程序 - parent.py和myscript.py,如下所示.parent.py在控制台中保持打印消息.并且myscript.py需要访问parent.py打印的内容.
parent.py:
import time
while 1:
time.sleep(1)
print "test"
Run Code Online (Sandbox Code Playgroud)
myscript.py:
import subprocess
p = None
p = subprocess.Popen(['python', 'parent.py'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
for line in p.stdout:
print line
Run Code Online (Sandbox Code Playgroud)
我希望myscript.py动态地捕获parent.py的输出.可以看出,parent.py有一个无限循环 - 脚本永远不会停止,但每当它输出单词'test'时,myscript.py也应输出相同的内容.但myscript.py没有给出任何输出.
我尝试用parent替换parent.py中的代码
print "Hello"
Run Code Online (Sandbox Code Playgroud)
程序完成执行后,myscript.py也打印出"Hello".所以我想除非parent.py的执行完成,否则myscript.py不会读取它.那是什么事吗?
我也尝试用这个片段替换myscript.py中的循环:
for line in iter(p.stdout.readline, ''):
print line
Run Code Online (Sandbox Code Playgroud)
仍然没有输出.
我的问题是:即使parent.py永远不会完成执行,我如何让myscript.py动态读取parent.py正在打印的所有内容.
(我发现了类似的问题,但是它们要么不起作用,要么根本没有答案.)
用户上传了一个 python 文件,我需要在服务器上执行该文件,并发回通过 WebSocket 创建的标准输出。执行的 python 文件将运行几分钟,我需要通过套接字返回标准输出,因为它们是实时“打印”出来的,而不是在脚本完成时。
我尝试过使用:Python。将 stdout 重定向到套接字,但这不是 WebSocket,我的 React 前端无法成功连接到它。(如果你能解决这个问题,那也能解决我的问题)
我也尝试过使用websocketd,但由于我无法sys.stdout.flush()在每个用户添加的打印语句之后添加,所以它不能解决我的问题。
我也尝试过使用子进程的 PIPE 功能,但也有相同的刷新问题
async def time(websocket, path):
while True:
data = "test"
await websocket.send(data)
# Run subprocess to execute python file in here
# sys.stdout => websocket.send
start_server = websockets.serve(time, "127.0.0.1", 5678)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
Run Code Online (Sandbox Code Playgroud)
这是python我正在使用的测试脚本:
async def time(websocket, path):
while True:
data = "test"
await websocket.send(data)
# Run subprocess to execute python file in here
# sys.stdout => …Run Code Online (Sandbox Code Playgroud) 假设我有一个进程打印出一些类似于这个ruby代码的数据.
1.upto(10) {
|i|
puts i
puts "\n"
sleep 0.6
}
Run Code Online (Sandbox Code Playgroud)
我想要一个生成此过程的python代码,并从中读取数据以将其打印出来.
import os
import sys
cmd = "ruby /Users/smcho/Desktop/testit.rb";
pingaling = os.popen(cmd,"r")
while 1:
line = pingaling.readline()
if not line: break
print line,
sys.stdout.flush()
pingaling.close()
Run Code Online (Sandbox Code Playgroud)
这段代码的问题在于它不会逐个打印数字.似乎python在最后一点打印出所有缓冲的数据.
有没有办法打印出没有缓冲的衍生过程的输出?
我正在运行 Django Web 服务器,并尝试将子进程的输出实时打印到日志中。如果我推荐 readline 行并取消注释 yowzer 行,我会得到所需的记录输出流,但是一旦我尝试按原样运行此行,我就不会得到任何输出。我究竟做错了什么?我能找到的所有结果似乎都表明这可以按原样工作。
sp = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
while sp.poll() is None:
logging.critical(sp.stdout.readline())
#logging.critical('yowzer')
time.sleep(10)
Run Code Online (Sandbox Code Playgroud)
谢谢你!
[4 月 3 日编辑]事实证明,问题不在于该命令长时间运行,而在于我使用分号将“su user”命令与主命令连接起来。删除 su 解决了这个问题。
我刚刚找到了这个很棒的 wget 包装器,我想使用 subprocess 模块将其重写为 python 脚本。然而,事实证明这很棘手,给了我各种各样的错误。
download()
{
local url=$1
echo -n " "
wget --progress=dot $url 2>&1 | grep --line-buffered "%" | \
sed -u -e "s,\.,,g" | awk '{printf("\b\b\b\b%4s", $2)}'
echo -ne "\b\b\b\b"
echo " DONE"
}
Run Code Online (Sandbox Code Playgroud)
然后可以这样调用:
file="patch-2.6.37.gz"
echo -n "Downloading $file:"
download "http://www.kernel.org/pub/linux/kernel/v2.6/$file"
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
来源: http: //fitnr.com/showing-file-download-progress-using-wget.html