英文:
How to pipe data from an ongoing process to a python script for processing
问题
我正在尝试开发一个用Python编写的GUI,以替代我正在与之合作的团队使用的命令行程序的输出。在高层次上,我尝试替代的程序会从一个板上读取一堆传感器的值,然后将它们的值输出到命令行终端,格式为一堆字段后跟一个值。目前这很麻烦,因为它经常跳来跳去,不够用户友好。我想直接获取板读取程序的输出,然后将其导入我的Python程序,该程序将提取字段和值,并相应地更新GUI。GUI在单独运行时似乎工作正常,但我在将其导入时遇到了一些问题。当它首次运行时,Python程序会挂起。我知道有更好的方法可以将板的输出导入GUI,但现在假设我只能访问将值打印到控制台的程序的控制台输出。
以下是代码示例,可以说明我的问题:
Bash模拟读数的脚本:
#!/bin/ksh
while :
do
echo ' - Sensor_1_reading: 21'
sleep 2
echo ' - Sensor_2_reading: 32'
sleep 2
echo ' - Sensor_3_reading: 232'
sleep 2
done
我的main-gui.py程序中的更新函数:
def update_function(self):
print("Running Update!")
if not sys.stdin.isatty():
print("Trying to read")
line = sys.stdin.read()
print(line)
else:
print("Nothing on stdin")
每当我在Ubuntu上使用WSL2运行以下命令时 source spammer.sh | python main-gui.py
,我会得到一个打印出"running update"然后"trying to read"的输出,然后程序挂起。发送键盘中断似乎会终止模拟器,此时Python程序将正常运行,GUI将出现。我已经寻找了其他解决方案,我确保设置了PYTHONUNBUFFERED环境变量,因为这似乎可能会导致问题。将Python设置为无缓冲并没有帮助。似乎这也与stdin需要EOF字符才能产生任何输入有关。有没有办法让Python程序在没有等待EOF的情况下接受stdin中的内容?有关如何解决这个问题的其他建议吗?
英文:
I'm trying to develop a gui in python to replace the output of a command line program that a team I've been working with is using. At a high level, the program I'm trying to replace reads a bunch of sensors from a board and then outputs their values to the command line terminal as a bunch of fields followed by a value. This is annoying currently because it frequently jumps around and isn't user friendly. I want to directly take the output of the board reading program and pipe it into my python program that will strip the fields and values and update a gui accordingly. The gui seems to be working fine on its own but I'm running into some issues with the python program hanging when it first starts running when piped into. I know that there are much better ways to get the output of the board into the gui, but for now, assume that I only have access to the console output from the program that prints the values to console.
Here's a snippet of code that can illustrate my example:
Bash spammer to simulate the readings
#!/bin/ksh
while :
do
echo ' - Sensor_1_reading: 21'
sleep 2
echo ' - Sensor_2_reading: 32'
sleep 2
echo ' - Sensor_3_reading: 232'
sleep 2
done
Function within my main-gui.py program
def update_function(self):
print("Running Update!")
if not sys.stdin.isatty():
print("Trying to read")
line = sys.stdin.read()
print(line)
else:
print("Nothing on stdin")
Whenever I run the following command on Ubuntu using WSL2 source spammer.sh | python main-gui.py
, I get a print out of "running update" and then "trying to read" which then hangs. Sending a keyboard interrupt seems to kill the spammer at which point the python program will run fine and the gui will appear. I've looked for other solutions and I've made sure that I set my PYTHONUNBUFFERED env variable as that could apparently cause issues. Making python unbuffered didn't help. It seems like it might also be related to the fact that stdin needs an EOF character before it will produce any input. Is there anyway to get the python program to ingest what there is on stdin without waiting for an EOF? Any other suggestions on how I could approach this problem?
答案1
得分: 2
使用与问题中完全相同的ksh脚本(我们称其为sensor.sh)和以下命名为Jul13.py的Python脚本:
while (s := input()):
print(s)
然后执行:
./sensor.sh | python Jul13.py
将生成:
- Sensor_1_reading: 21
- Sensor_2_reading: 32
- Sensor_3_reading: 232
- Sensor_1_reading: 21
- Sensor_2_reading: 32
- Sensor_3_reading: 232
*无限循环*
英文:
With the ksh script exactly as shown in the question (let's call it sensor.sh) and a Python script named Jul13.py as follows:
while (s := input()):
print(s)
...then...
./sensor.sh | python Jul13.py
...will generate...
- Sensor_1_reading: 21
- Sensor_2_reading: 32
- Sensor_3_reading: 232
- Sensor_1_reading: 21
- Sensor_2_reading: 32
- Sensor_3_reading: 232
ad infinitum
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论