-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Process.start detachedWithStdio stdout is buffered when not desired #44573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
//cc @aam |
Programs usually default to buffering stdout whenever stdout is not a terminal, such as a file or in a pipe in this case ( If the program is in fact flushing its buffers on newlines, and Dart doesn't pipe it, then there is a bug in Dart. But we need to confirm that is the case before jumping to that conclusion. If you just want to forward stdout and stderr and not capture them, and not input anything on stdin, then you can use |
So, my goal is to write a CLI tool in Dart that you can call from the terminal, and then it will in turn launch another program also in the terminal. I guess the problem is that, I don't know how to tell the process that I'm starting to behave as if it is being run from the terminal, that's what I actually want. Think of it like: I can write a BASH script and have that launch various programs, and their output goes to the terminal as expected... I'd like to do something similar but written in Dart (that way it can be smarter). It might also be helpful to have my Dart app watching stdout/stderr for various reasons, but in the end I need it to be the case that any output from the launched process shows up to the end user in the terminal... On linux there is a trick to force the process you are launching to behave as if it is being called from a terminal, but not sure how to do such a thing on Windows. Hope this makes at least some sense. :) |
@Sidewinder1138 how quickly does the buffering kick in for you? I was trying to reproduce this effect and couldn't. Here is the sample program I used - it seems to be producing the output on the console as I ran it in Windows cmd window: pipe.dart:
#include <stdio.h> int main(int argc, char** argv) {
c:> dart.exe pipe.dart
|
Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. Please don't hesitate to comment on the bug if you have any more information for us; we will reopen it right away! |
This provides the guts of an implementation of zulip#60. I'd have liked to write this in Dart, rather than in shell. But when running this script interactively (vs. in CI), a key ingredient for a good developer experience is that the child processes like `flutter test` should have their stdout and stderr connected directly to those of the parent script, i.e. to the developer's terminal. Crucially, that lets those processes know to print their output in a form that takes advantage of terminal features to get a good interactive experience. The gold standard for a CLI tool is to have a way to control that choice directly, but `flutter test` and some other Dart-based tools lack that capability. And in Dart, as far as I can tell, there simply is no way to start a child process that inherits any of the parent's file handles; instead the child's output will always be wired up to pipes for the parent to consume. There's advice for how the parent can copy the output, chunk by chunk, to its own output: dart-lang/sdk#44573 dart-lang/sdk#5607 https://stackoverflow.com/questions/72183086/dart-dont-buffer-process-stdout-tell-process-that-it-is-running-from-a-termina but that doesn't solve the problem of the child's behavior changing when it sees a pipe instead of a terminal. The nastiest consequence of this behavior is that the output of `flutter test` is hundreds of lines long, even for our small codebase, even when only a single test case fails or none at all. That's fine in CI, but pretty much intolerable for a development workflow. So, shell it is. (Python, or Javascript with Node, or many other languages would also handle this just fine, but would mean an extra system of dependencies to manage.) Specifically, Bash. --- Fortunately, using Bash does mean we get to reuse the work that's already gone into the `tools/test` script in zulip-mobile. This commit introduces a bare-bones version, with most of the features (notably --diff and its friends) stripped out, and the test suites replaced with a first two for our codebase. This version also uses `set -u` and `set -o pipefail`, unlike the one in zulip-mobile, in addition to `set -e`.
I'm trying to use Process.start on Windows to just launch an app (I'm making a CLI tool), and then output that app's stdout/stderr to terminal. It works, but I noticed that the stdout is being buffered, it outputs in "real-time" at first, but then halts, and only when I kill the launched process does it dump all the remaining output.
Here's what I'm doing:
I've looked at #5607, but it was just closed as if this isn't a problem, which I'm pretty sure it is, at least on Windows.
I'm running from cmd.exe, inside Windows Terminal.
The text was updated successfully, but these errors were encountered: