funnelling data into a daemonised non-daemon, using shell commands
This is what I want to do:
$ serverise normally-barely-interactive-program-that-uses stdin stdout &
unique-id-221B
$ clienty 221B "Astonishing!"
Elementary
$ clienty 221B "what did I just say?"
'Astonishing', although the methods are simple and easily followed, once explained.
$ clienty 221B "so, you persist between invokations of the client?"
Indeed.
I have tried dual named pipes, but they only last one invocation. I think this is because the server side gets an EOF, and so assumes that stdin has be开发者_JAVA技巧en closed by the user.
Sockets seem to be the way to go, but most of the wrappers assume an http-like model, and fork off a new program each time someone connects. Socat seems okay, but it also dies after just one go.
I have seen Gnu Screen and Tmux used for this, but this seems overkill, and to be honest, I can't assume that the user's environment won't contain either, and thus any solution like this would be a bit fragile in the face of non-standard configs of those. It also seems like a bit of overkill.
This seems like a problem that would have come up before, so I must be looking in the wrong place for the snazzy little utility that does this.
Regarding your problem with named pipes only lasting one invocation: if that's indeed your only problem, it's an easy one to work around. (my sample barely interactive program happens to be bc
)
$ mkfifo in out
$ while read line <in; do echo "$line"; done | bc >out &
$ cat out &
$ echo "1+1" >in
2
$ echo "2+2" >in
4
This works by reopening the input pipe to only read one line at a time, while writing to a single unnamed pipe that is only opened once for the whole session.
Note that:
- input is constrained to a line at a time
- the output stream has the same issue of needing to only be opened once
This is impossible in the generic case you describe.
You describe something that looks mostly like a query/reply service, but with only stdin and stdout, your barely-interactive-program doesn't provide a way to know which query each reply goes to.
In your example, consider your first clienty
invocation. Obviously, the query 'Astonishing' could be transfered to the server's stdin directly, and it seems like the server would write 'Elementary' on its stdout. But what then? Should the wrapper transfer it immediately? Buffer it? How does it know whether the answer is complete? Assuming you'd solved that, if multiple clients are querying at the same time, how does it know which one to send the answer back to?
You need a minimum amount of protocol to solve that. It could be as simple as "replies are single-line, guaranteed and ordered."
精彩评论