6

I'm looking for something like a persistent named pipe... something that I can cat or grep multiple times, and always get the current state of whatever process is feeding into the pipe.

For example, let's say that I create a named pipe called /tmp/timestamp, and then use date to write to it:

mkfifo /tmp/timestamp
date --iso-8601=seconds > /tmp/timestamp

At this point, the call to date will block, waiting for /tmp/timestamp to be read ...

cat `/tmp/timestamp`

Will un-block date, I'll see something like 2017-03-18T16:11:54-04:00 written to stdout, and date will terminate.

... but what if I want an updated date every time I cat /tmp/timestamp?

I guess that

while :; date --iso-8601=seconds > /tmp/timestamp; done

will work, but I'd like to know if a) there are any non-obvious issues with this approach and b) if there's a way to do it which doesn't require a loop.

I would also like to set this up so that it launches automatically, making the fifo always available.

In terms of why I want this to be in pipes -- the information in question is stored in a database backing a web application. Most of our tech support folks are entirely comfortable logging into the servers via ssh and running queries against the database, but there are certain vital statistics that would be really handy to simply grep from files. Being able to ls the directory containing the named pipes would make all of this discoverable... essentially, I'm not doing this because I have to, I'm doing it because it's a metaphor that I think will work well.

  • 2
    Can you explain why you need it to be a pipe, instead of forking a subprocess (with a script, or whatever) and reading stdout from this subprocess whenever you'd "access the file"? The condition "update output everytime I read" doesn't match the "a file is a stream of bytes" abstraction particularly well. – dirkt Mar 19 '17 at 10:30
  • "everytime I read" sounds more like a network service one would connect to, not a filesystem object – thrig Mar 19 '17 at 14:50
  • Is there any reason something like netdata wouldn't work to get the statistics you need? That has the added advantage that it gives you charts of the statistics over however long of a period you tell it to retain data for. – Austin Hemmelgarn Aug 17 '17 at 19:22
  • Hey... I'm looking for a solution like this too. My use case is that I have a open-source program (Kibana, in this case) that wants to read a configuration file. I need to generate the file dynamically, when kibana reads its configuration. Sockets are out of the question as they can't be opened like regular files, and modifying kibana is also out. I've a few other programs that I need to treat similarly. – Chris Cogdon Dec 5 '17 at 17:25
2

You could implement a custom filesystem either as a kernel module or by using fuse. Within that custom filesystem you can then have whatever virtual files you want.

2

Here's a "non-obvious issue" with the loop: if a reading process holds the fifo open (because, say, it blocks on opening another file or is suspended), the write loop will run continuously (until it fills the fifo buffer). There are also issues with multiple concurrent readers, but perhaps you can reasonably eliminate that possibility.

As for a non-loop solution, you can use a socket instead of a fifo, but then you have to write a (trivial) reader program (and use pipes if you want to run something other than cat) since you can't just open those.

  • Actually not; the shell first opens the pipe to do the redirection, which waits for a reader, and only when that completes it exec's date which calls time() and gets almost exactly the time the reader opened. – dave_thompson_085 Apr 11 '18 at 7:52
  • @dave_thompson_085: Indeed (under O_NONBLOCK); I replaced that part with true statements. Thanks for the reminder. – Davis Herring Apr 12 '18 at 3:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.