Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
|
06-11-2024, 12:44 PM
|
#1
|
Senior Member
Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,460
Rep:
|
What is the best way to capture output?
I have an application generating output at a high rate. Milliseconds. The output is appended to a file in /dev/shm so it's fast enough and won't tax the SSD.
Now, I need to capture that output with another application which I will write in a scripting language. It basically "slurps" the output file at very short (milliseconds) intervals.
I've given up on this idea before, I want to try again. I remember there were a number of pitfalls, mainly around the problem of "skipping beats."
The last time, I tried it with mkfifo but I didn't have a good experience. It was awkward because the capture wouldn't really begin until I opened the receiving end of the fifo with tail and I wish I could avoid that. I think the flow also got interrupted after some time as if it was exhausted or broken or something.
In the Windows 9x era, that would be done with COM or DDE I guess. What about Linux? What other approaches can you suggest? Networking? Sockets? Something else?
|
|
|
06-11-2024, 05:49 PM
|
#2
|
LQ Guru
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,323
|
Can’t you have one program write to standard output, and one program read from standard input, and pipe one into the other?
|
|
|
06-11-2024, 06:21 PM
|
#3
|
Senior Member
Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,460
Original Poster
Rep:
|
Yes, that would be the obvious solution. But it's a Windows application running on Wine. It can write "logs" to disk but it can't send data to standard output. It's not stdout-aware.
|
|
|
06-11-2024, 06:22 PM
|
#4
|
LQ Guru
Registered: Oct 2004
Distribution: Arch
Posts: 5,219
|
Rewrite the first program so that it does both at once with the output.
Code:
for i in {1..10}; do
echo "$i" | tee -a a1.txt
sleep .2
done
Show what the first program is doing. The source code for it. Or the docs for it.
|
|
|
06-11-2024, 06:38 PM
|
#5
|
Senior Member
Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,460
Original Poster
Rep:
|
You don't understand. It's a third-party app provided by a client. I didn't write it and I don't have the source. It just writes to disk, it's all I have. Best I can do is make it write to a RAM disk. In fact, it writes to a symlink that points to /dev/shm. It thinks it's a regular directory.
Last edited by lucmove; 06-11-2024 at 06:39 PM.
|
|
|
06-12-2024, 01:39 AM
|
#6
|
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,924
|
What are you going to do when the RAM-disk becomes full? Have you got some log-rotating mechanism?
|
|
1 members found this post helpful.
|
06-12-2024, 06:03 AM
|
#7
|
LQ Addict
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,702
|
so the best way is still to create a fifo, and ask that app to write into it. You only need to open it before, like tail -f fifo or similar and you can redirect its output anywhere you want. Or capture it with your script (pipe it to any other app).
/dev/shm is not a regular directory, in /dev there is nothing "regular", but anyway you can use that if you wish.
|
|
|
06-12-2024, 10:46 AM
|
#8
|
Senior Member
Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,460
Original Poster
Rep:
|
Quote:
Originally Posted by NevemTeve
What are you going to do when the RAM-disk becomes full? Have you got some log-rotating mechanism?
|
I'm glad you asked. The log doesn't append, it overwrites. So the log file is always one line only. So you made me remember that there was this problem of the file being not found by the capturing program every once in a while. Easy problem to handle from the capturing program's standpoint, but I vaguely remember that it was a problem for the fifo idea.
|
|
|
06-12-2024, 10:49 AM
|
#9
|
LQ Addict
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,702
|
hm. you cannot delete anything from the fifo, if you sent something into it. So it will accept all the lines one by one. Probably the app will reopen it every time, but it does not really matter. As far as I see.
|
|
|
06-12-2024, 12:05 PM
|
#10
|
Senior Member
Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,460
Original Poster
Rep:
|
I'm running tests. I find fifo very unreliable.
Terminal A:
$ mkfifo myfifo.fifo
Terminal B:
$ less -f myfifo.fifo
(empty)
Terminal A:
$ echo test1 > myfifo.fifo
Terminal B:
test1
Terminal A:
$ echo test2 > myfifo.fifo
Terminal B:
test1
test2
Terminal A:
$ echo test3 > myfifo.fifo
Terminal B:
test1
test2
test3
First problem: I don't want to retrieve a list. I don't want it piling up in any way. Why is it piling up?
Another test:
$ watch less -f myfifo.fifo
That doesn't even work. It won't capture.
Back to the other test. A simple repeat:
Terminal A:
$ mkfifo myfifo.fifo
Terminal B:
$ less -f myfifo.fifo
(empty)
Terminal A:
$ echo test1 > myfifo.fifo
Terminal B:
test1
Terminal A:
$ echo test2 > myfifo.fifo
Terminal B:
test1
Terminal A:
$ echo test3 > myfifo.fifo
Terminal B:
test1
test3
Terminal A:
$ echo test2 > myfifo.fifo
Terminal B:
test1
test3
test2
Why did the first "test2" miss this time around? Why did I have to repeat it? It didn't miss the first time but it did now. Why does that happen? That cannot happen. If it does, fifos are unfit for the purpose.
|
|
|
06-12-2024, 01:41 PM
|
#11
|
LQ Addict
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,702
|
I don't really understand, timing can be important. If you want to read the same fifo both in A and B you need to use tee or some other tool to duplicate the output. Otherwise it may not really do what you expect.
Don't forget they are buffered (too).
|
|
|
06-12-2024, 03:11 PM
|
#12
|
Senior Member
Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,460
Original Poster
Rep:
|
But it's not both reading. Terminal A writes (echo >) and Terminal B reads.
The timing is manual, I mean, I have two terminal windows open, I "write" in one then switch to the other one manually to see what happened then switch back to write again and so on. It's nothing really fast.
|
|
|
06-12-2024, 06:06 PM
|
#13
|
Senior Member
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,793
|
Hmm, I get quite different results from you.
Quote:
Terminal A:
$ mkfifo myfifo.fifo
Terminal B:
$ less -f myfifo.fifo
(empty)
|
In this case, I get
Code:
test1
myfifo.fifo (END)
and I have to quit less before I can see any further data.
Quote:
$ watch less -f myfifo.fifo
That doesn't even work. It won't capture.
|
This works fine for me. I tried
Code:
for n in {1..3} ; do echo test$n > myfifo.fifo ; sleep 1 ; done
in terminal A, and
Code:
watch less -f myfifo.fifo
in terminal B, and I saw "test1" then "test2" and "test3" each in turn.
Maybe some behaviour of less has changed? I'm running on a somewhat old system.
Code:
less 487 (GNU regular expressions)
Anyway, I don't think it makes much sense to use less on a fifo. Probably cat is better for testing.
|
|
1 members found this post helpful.
|
06-12-2024, 09:07 PM
|
#14
|
Senior Member
Registered: Aug 2005
Location: Brazil
Distribution: Debian
Posts: 1,460
Original Poster
Rep:
|
You are right, cat has more consistent behavior.
But anyway, I found that the Windows application cannot write to a named pipe. I'm not sure what happens but it just won't work. Nothing is written, I can't read the other end of the pipe at all. It has to be a regular text file.
|
|
|
06-13-2024, 05:01 AM
|
#15
|
LQ Addict
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,702
|
Quote:
Originally Posted by lucmove
You are right, cat has more consistent behavior.
But anyway, I found that the Windows application cannot write to a named pipe. I'm not sure what happens but it just won't work. Nothing is written, I can't read the other end of the pipe at all. It has to be a regular text file.
|
It is not cat, but buffering. But it is not important any more, if your app cannot use a pipe. I would check if that was a permission issue and/or if your app can use stdout or some other way. You cannot easily collect that output, if that file is continuously overwritten (you will never know if you missed something or if the file is overwritten during the read or ??)
|
|
|
All times are GMT -5. The time now is 01:56 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|