- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个用 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
andsetvbuf
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/
我有一个发出值的 Observable 源 source1,如果它没有发出任何东西超过 2 秒,我想切换到后备源 source2。如果 source1 再次发射,我想从中发射。依此类推,无限期。 到目
我正在使用 postfix 发送电子邮件。当我将电子邮件发送到其他域时它工作正常,但是当我将电子邮件发送到配置后修复的同一个域时它不发送电子邮件。 下面是我的配置: myhostname = [FQD
我最近将 ipython 和 pandas 更新为最新的稳定版本。它导致 matplotlib 中出现了一些奇怪的行为,如果我从终端运行(以前的行为)脚本,我将无法显示数字。如果我在 ipython
我的应用程序是一个网络应用程序。它的工作是接收我想将它们作为信号发出的数据包流(QByteArray)。这样做会不会效率低下?我关心复制大缓冲区。 最佳答案 QByteArray 使用 Copy-on
有 QTableWidget。我需要发送带有行列和文本的 cellChanged 信号。我怎样才能做到这一点? —— 我已经用插槽连接了信号。我需要发送 信号。 最佳答案 您必须使用 connect
我编写了一个简单的玩具语言编译器前端,它使用 llvm-sys 生成 LLVM IR (LLVM 的 C library 的 Rust 绑定(bind))。然后我通过创建 LLVMTargetMach
我想知道如何像那里描述的那样发出 HTTP POST 请求 http://code.google.com/apis/documents/docs/3.0/developers_guide_protoc
简单的问题。我需要在 GWT 中发出一个重定向到新页面的 GET 请求,但我找不到正确的 API。 有吗?我应该自己简单地形成 URL 然后做 Window.Location.replace ? (原
我正在使用 paging3我有两个不同的寻呼源。问题是Coroutine Scope只发出第一个寻呼流 在 ViewModel我有两个分页流程 val pagingFlow1 = Pager(Pagi
docker doc 中没有任何解释,也没有 docker 中看似任何内置变量来查找构建图像的原始工作目录。 我想在不同的目录上运行命令,并在某个时候回到我启动 docker build 的位置。 我
我试图使一个puppeteer.js机器人能够暂停并恢复其工作。 总的来说,我有一个带有十几个异步方法的类,事件发射器和一个名为“state”的属性,该属性使用setter进行更改。当我发生事件“停止
这个问题已经有答案了: Is it possible to send custom headers with an XHR ("Ajax" request)? (1 个回答) 已关闭 4 年前。 我想
如果浏览器打开与远程服务器的连接,是否可以通过 Javascript 访问同一连接? 我的网络上有一个小型以太网模块,我的编程有点像这样(伪代码): private var socket while(
尝试发出 HTTP 请求时,出现错误: {-# LANGUAGE OverloadedStrings #-} import Network.HTTP.Conduit -- the main modul
我有这个异步任务: public class likeTheJoke extends AsyncTask{ @Override protected Void doInBa
当进程终止并为其发出 wait() 时会发生什么?当一个子进程终止但没有人为其执行 wait() 时会发生什么?如果对尚未终止的进程执行 wait() 会发生什么情况? 最佳答案 如果我误解了这些问题
我尝试使用以下小部件结构、信号连接和回调将与 GtkTextView 支持的击键相关的信号(CTRL+a、CTRL+x 等)附加到工具栏按钮: typedef struct { GtkWidg
我有以下 base64 编码的字符串,我需要使用 Swift 对它进行 base64 解码: KimHser2RvFf9RPjajWO4K/odT51hTlISwMKNIfPUC+gXYZKNjGDC
我正在使用 Facebook Messenger webview 显示表单,在提交时,我想将消息发送回用户并关闭 webview。我现在的问题是 webview/浏览器没有发送消息就关闭了。我不知道这
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我是一名优秀的程序员,十分优秀!