gpt4 book ai didi

python - 在发出 CTRL+C 命令之前弹出读取数据

转载 作者:太空宇宙 更新时间:2023-11-04 01:47:25 25 4
gpt4 key购买 nike

我有一个用 C 语言编写的命令行工具,用于通过串行 USB Dongle 扫描蓝牙设备的 Windows。

它将循环遍历范围内的所有设备,重复直到它收到 CTRL+C 命令。

device1 name firmware
device2 name firmware
device3 name firmware
device1 name firmware
device2 name firmware
device3 name firmware
...

我想在扫描到达某个设备时停止扫描,以便发出更新固件命令。

目前,我只能在使用以下启动扫描、休眠、然后发出 CTRL+C 命令的函数发出 CTRL+C 命令后捕获输出,然后我捕获错误并在except block :

        command = [self.cli_tool, '-s']

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE

stream = []

if self.check_dongle_firmware() is not False:
try:
self.proc = subprocess.Popen(
command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
startupinfo=startupinfo)

time.sleep(SCAN_TIMEOUT)
os.kill(self.proc.pid, signal.CTRL_C_EVENT)
self.proc.wait()

except KeyboardInterrupt:
for line in self.proc.stdout:
stream.append(line)

for x in stream[7:]:
x = x.decode()
print(x.strip())

我想要这样的东西:

stream = []

self.proc = subprocess.Popen(
command, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
startupinfo=startupinfo)

for line in self.proc.stdout:
stream.append(line)
if 'device2' in line.decode().split():
os.kill(self.proc.pid, signal.CTRL_C_EVENT)
self.proc.wait()

虽然这不起作用。它不会一次读取 1 行,并且永远不会到达 CTRL+C 事件。

我需要一次读取和处理 1 行,以便我可以在某个设备上停止进程。

目前它只读取空字节或字符串,具体取决于管道属性。

打印到屏幕(关闭启动信息)或保存到文件而不发出 CTRL+C 将呈现为空。我尝试了各种组合:

universal_newlines=True

bufsize=1

self.proc.communicate()[0]

当我使用 ping 之类的命令尝试代码时,我没有问题并且可以完全控制输出。

我已经搜索过 SO 以尝试任何看起来相似但都无法满足我需要的东西。

我想我遗漏了一些明显的东西,或者由于该工具未在 C 代码中应用刷新命令而无法实现?

如有任何指示或建议,我们将不胜感激!

在 C 代码中,我仅在以下位置使用 fflush,我认为这些位置用于错误处理。

bootloader\src\common\receiver\src\common\ 中的

project.h

//*************************************************************************
//------------------------- assertion of errors --------------------------
//*************************************************************************
/*
* The format is assert(eval, error);
*
* If 'eval' equals 0 then there is an error printed with number 'error'.
*
*/

#define ERR_STACKOVERFLOW 0 // Out of stack space
#define ERR_SCH_OVERFLOW 1 // Scheduler overflow
#define ERR_SCH_OUTRANGE 2 // Scheduler out of range
#define ERR_WSHRS_OUTRANGE 3 // Scheduler out of range

#ifdef __nDEBUG__

#include "./error/error.h"
....
#include <stdio.h>
#define DBG_PRINT(a, args...) { printf(a, ##args);fflush(stdout); }

最佳答案

这里的问题可能是,您的 CLI 程序的输出是 block 缓冲的,因为输出文件描述符与终端无关。您声称,它适用于“ping”而不是您的 cli 程序,因此它肯定是子进程本身的问题。

由于您自己编写了 cli 程序,请确保它不会缓冲输出(即在打印的每一行之后放置一个 fflush()

具体调整代码如下:

while (somecondition) {
...
printf("%s %s %s\n", device, name, firmware);
fflush(stdout); // <- Add this line after the printf
...
}

或者,如 melpomene 所建议的,您还可以在程序的早期将 stdout 切换为行缓冲:

setvbuf(stdout, NULL, _IOLBF, 0);

Online C11 standard , 7.21.3/3:

When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions.

7.21.3/7:

At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

关于python - 在发出 CTRL+C 命令之前弹出读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51037769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com