Suppose some application
app runs as a systemd service, and there is a need to communicate with it via the command line. Something like this:
$ sudo systemctl start app
> set parameter X to value Y
What would be the proper way to create such behavior? I.e. be able to enter the
app's cli from the shell?
Any old Unix IPC mechanism would work. Named pipes, unix sockets, or even a TCP socket.
There many ways to do that. The first and simplest: a configuration file (for example in
/etc/app/) and restart the service when you change the file. Another if you need runtime changes without restarting the service is communication via pipes/sockets/etc, to do that you need two binaries, a server and and client.
So essentially the server will be running as a service, while the client will take input and send it to the server via pipes/sockets/etc?
Thank you! Guess I will try to find some good crate for instance for named pipes then (since the performance is not an issue in this particular case, perhaps the simplicity can be prioritized).
You can use
nix::unistd::mkfifo from the
nix crate to make the named pipe. Both your server and client can open it. Note however that named pipes are not suitable if you want to have multiple clients or want to have both client and server write to it. For that you did better use a unix domain socket. This allows you to have multiple clients and to handle bidirectional communication. You can either use
std::os::unix::net::UnixDatagram if you want to send and receive data in concrete packets or
std::os::unix::net::UnixListener (server side) and
std::os::unix::net::UnixStream (client side) if the commands may be of arbitrary length. In the later case you have to implement packet segmentation yourself, just like you would for a pipe.
By the way if you use unix domain sockets, you can use so called "socket activation" to make systemd start the service when someone actually tries to use it rather than at boot time. This reduces the time it takes to boot your system.
Thanks a lot, will try this out!
For local system services on Linux you may not want to implement your own protocol over a socket. It is more recommended to use d-bus (I can suggest the
zbus crate), or if you need remote access, use one of the many web frameworks to add a REST API over HTTP.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.