I am trying to do animation in the terminal by printing and flushing repeatedly. Is there a way to flush the standard output after writing to it in ATS?
Thank you!
I suppose that you can just do
val () = fileref_flush(stdout_ref)
If you need to do this all the time, then you may want to use 'setbuf' to disable buffering.
Related
I've spotted something that I find very puzzling about the behavior of System.cmd. I just wanted to ask if anyone might have thoughts on what I may be doing wrong or what may be going on.
I've been trying to wrap an Elixir script around the ack programmer's grep. I tried this:
{_message, errlevel} = System.cmd("ack",[])
And I get back the help text that ack displays on an empty command line; I won't bother to reproduce it here because it's not necessarily germane to the question.
Then I try this:
{_message, errlevel} = System.cmd("ack",[""])
And it looks like iex hangs. Now I realize in the first case the output may be going to stderr rather than stdout. But there's another reason I'm asking about this; I found something even more interesting to me. Because I'm not 100% committed to using ack I thought I'd try ripgrep on the thought that it might interact with stdout better.
So if I do this:
{_message, errlevel} = System.cmd("rg",[])
Same as ack with no arguments--shows me the help text. Again I'm guessing it's probably out to stderr. I could check to confirm my assumption but what's even more interesting to me is that when I do this:
{_message, errlevel} = System.cmd("rg",[""])
It hangs again!
I had always figured the issue is with how ack interacts with stdout but now I'm not so sure since I see the same behavior with ripgrep. This is Elixir 1.13.2 on MacOSX 13.1. I've seen this same behavior with older versions of MacOSX.
Any idea how I can get the ack and/or ripgrep process to terminate so I get a response back? I've seen this https://hexdocs.pm/elixir/main/Port.html#module-zombie-operating-system-processes and I can try it but I was hoping for something slightly less hacky, I guess. Any suggestions? Also if I use the :stderr_to_stdout option set to true, it doesn't seem to make any difference.
I've seen this Q & A but I'm not totally clear on how using Task.start_link would help in this case. I mean would one do a Task.start_link on System.cmd?
You are executing a command that expects input on STDIN, but with System.cmd/3, there is no mechanism to provide the input.
Elixir has no way to know the behaviour of the command you are executing, so waits for the process to terminate, which never happens. As José mentioned on the issue Roger Lipscombe raised, this is expected behaviour.
If you want to send the OS process input via STDIN, you need to use Ports. However, there are limitations there too, which I asked about here.
For ack specifically, it reads from STDIN if you don't provide a filename. So you can workaround the limitation by putting the data in a file, and providing the filename as an argument, rather than piping the data via OS streams.
Looks like a bug. I've filed https://github.com/elixir-lang/elixir/issues/12321.
Hello I have a scenario where the only thing I should do is to output data and I must use DMA. Which one is the best option ifI only have to output data,write back or write through and why? Thank you!
I have a tcl script which takes a few minutes to run (the execution time varies based on different configurations).
I want the users to have some kind of an idea of whether it's still executing and how long it would take to complete while the script executes.
Some of the ideas I've had so far:
1) Indicate it using ... which keep increasing with each internal command run or so. But again it doesn't really give a sense of how much more to go for a first time user.
2) Use the revolving slash which I've seen used many places.
3) Have an actual percentage completed output on screen. No idea if this is viable or how to go about it.
Does anyone have any ideas on what could be done so that users of the script understand what's going on and how to do this?
Also if I'm implementing it using ... , how do I get them to print the . on the same line each time. If I use puts to do this in the tcl script the . just gets printed on the next line.
And for the revolving slash, I would need to replace something which was already printed on screen. How can I do this with tcl?
First off, the reason you were having problems printing dots was that Tcl was buffering its output, waiting for a new line. That's often a useful behavior (often enough that it's the default) but it isn't wanted in this case so you turn it off with:
fconfigure stdout -buffering none
(The other buffering options are line and full, which offer progressively higher levels of buffering for improved performance but reduced responsiveness.)
Alternatively, do flush stdout after printing a dot. (Or print the dots to stderr, which is unbuffered by default due to mainly being for error messages.)
Doing a spinner isn't much harder than printing dots. The key trick is to use a carriage return (a non-printable character sometimes visualized as ^M) to move the cursor position back to the start of the line. It's nice to factor the spinner code out into a little procedure:
proc spinner {} {
global spinnerIdx
if {[incr spinnerIdx] > 3} {
set spinnerIdx 0
}
set spinnerChars {/ - \\ |}
puts -nonewline "\r[lindex $spinnerChars $spinnerIdx]"
flush stdout
}
Then all you need to do is call spinner regularly. Easy! (Also, print something over the spinner once you've finished; just do puts "\r$theOrdinaryMessage".)
Going all the way to an actual progress meter is nice, and it builds on these techniques, but it requires that you work out how much processing there is to do and so on. A spinner is much easier to implement! (Especially if you've not yet nailed down how much work there is to do.)
The standard output stream is initially line buffered, so you won't see new output until you write a newline character, call flush or close it (which is automatically done when your script exits). You could turn this buffering off with...
fconfigure stdout -buffering none
...but diagnostics, errors, messages, progress etc should really be written to the stderr stream instead. It has buffering set to none by default so you won't need fconfigure.
I am working on Windows XP, and I was wondering is there anyway to get the output from stdout and write it to a file. I need to be able to write to the console and a file, but using something like tee won't work.
My boss is working on an application that takes a while and he is writing to the console. At the end, he wants to rewind stdout for some lines and then write the output to a file. He believes that writing to file every time that something is written to the screen is too much I/O. I may be completely wrong, but isn't that how the tee command works? Stdout is piped into tee which then writes the output to the console and then the designated file.
Is this possible? I know that stdout is a file descriptor, so I was thinking that it should be possible because you can rewind other files, but is stdout write-only? I know in Unix that stdout is the file dev/stdout.
Thanks
This is what tee (or redirecting streams generally) is for. Strictly speaking, you can't "rewind" stdout. That's why you'd redirect it elsewhere if you needed to see its data later.
I am suspicious of the "it's too much IO to write to a file and to the console" assertion: to me that smacks of premature optimization. However, assuming that is actually true...AND assuming you don't want to redirect your output, the only other choice I see is holding it in memory until you're ready to write it out. You could come up with a fancy scheme which allocated a block of memory and wrote to it (and the console) then flushed it as it became full...but that seems like a lot of trouble to go to.
How much IO we talking here?
You can use a pipe to redirect stdout to a file. You can display the content of the file later.
Have a look at this example: Creating a Child Process with Redirected Input and Output
I've written a Windows application using the native win32 API. My app will launch other processes and capture the output and highlight stderr output in red.
In order to accomplish this I create a separate pipe for stdout and stderr and use them in the STARTUPINFO structure when calling CreateProcess. I then launch a separate thread for each stdout/stderr handle that reads from the pipe and logs the output to a window.
This works fine in most cases. The problem I am having is that if the child process logs to stderr and stdout in quick succession, my app will sometimes display the output in the incorrect order. I'm assuming this is due to using two threads to read from each handle.
Is it possible to capture stdout and stderr in the original order they were written to, while being able to distinguish between the two?
I'm pretty sure it can't be done, short of writing the spawned program to write in packets and add a time-stamp to each. Without that, you can normally plan on buffering happening in the standard library of the child process, so by the time they're even being transmitted through the pipe to the parent, there's a good chance that they're already out of order.
In most implementations of stdout and stderr that I've seen, stdout is buffered and stderr is not. Basically what this means is that you aren't guaranteed they're going to be in order even when running the program on straight command line.
http://en.wikipedia.org/wiki/Stderr#Standard_error_.28stderr.29
The short answer: You cannot ensure that you read the lines in the same order that they appear on cmd.exe because the order they appear on cmd.exe is not guaranteed.
Not really, you would think so but std_out is at the control of the system designers - exactly how and when std_out gets written is subject to system scheduler, which by my testing is subordinated to issues that are not as documented.
I was writing some stuff one day and did some work on one of the devices on the system while I had the code open in the editor and discovered that the system was giving real-time priority to the driver, leaving my carefully-crafted c-code somewhere about one tenth as important as the proprietary code.
Re-inverting that so that you get sequential ordering of the writes is gonna be challenging to say the least.
You can redirect stderr to stdout:
command_name 2>&1
This is possible in C using pipes, as I recall.
UPDATE: Oh, sorry -- missed the part about being able to distinguish between the two. I know TextMate did it somehow using kinda user visible code... Haven't looked for a while, but I'll give it a peek. But after some further thought, could you use something like Open3 in Ruby? You'd have to watch both STDOUT and STDERR at the same time, but really no one should expect a certain ordering of output regarding these two.
UPDATE 2: Example of what I meant in Ruby:
require 'open3'
Open3.popen3('ruby print3.rb') do |stdin, stdout, stderr|
loop do
puts stdout.gets
puts stderr.gets
end
end
...where print3.rb is just:
loop do
$stdout.puts 'hello from stdout'
$stderr.puts 'hello from stderr'
end
Instead of throwing the output straight to puts, you could send a message to an observer which would print it out in your program. Sorry, I don't have Windows on this machine (or any immediately available), but I hope this illustrates the concept.
I'm pretty sure that even if you don't separate them at all, you're still not guaranteed that they'll interchange one another in the correct order.
Since the intent is to annotate the output os an existing program, any possible interleaving of the two streams must be correct. The original developer will have placed appropriate flush() calls to ensure any mandatory ordering is honoured.
As previously explained, record each fragment that is written with a time stamp, and use this to recover the sequence actually seen by the output devices.