Assuming a minimal example like in this question, except for another shell script.

[email protected]:

Description=Foo Service
After=network.target systemfoo.socket

ExecStart=/bin/bash /opt/foo/foo.sh



Description=Foo Socket
[email protected]





while true; do
    logger -t FOO "Connection received: $REMOTE_ADDR $REMOTE_PORT"

When I connect via

nc 7780

the script is invoked correctly. But when I quit nc with CTRL-C, the script runs forever.

Is there a mechanism to send a SIGTERM to the script process, when closing the socket (I assume nc does that when quitting)?

1 Answer 1


No, systemd won't stop the service when the connection is closed.

The reason that is not possible is that, once systemd has accepted a new connection to the socket it's listening on, it will pass that socket to the service started to handle the connection and it will no longer keep any reference to that connection.

In order to detect when the connection was closed by the client, you need to check the socket from the service itself, by reading from stdin or by polling it to check whether it was closed.

  • The connection is coming from an INET socket while the process communicates via stdin and stdout. I thought there is some kind of systemd-managed proxy in between. So systemd has control over the socket.
    – gerion
    Jun 6, 2019 at 8:01
  • @gerion No, there's no proxy. Stdin and stdout of the process forked by systemd are simply opened (using dup() syscall) to copies of the file descriptor of the socket that was just accepted. But once systemd forks the service process, it closes its own copy of that file descriptor. None if this is really new, inetd would do the same, fork a process to handle an accepted connection, mapping the socket to stdin+stdout of the forked process. systemd doesn't keep any reference to the connection socket.
    – filbranden
    Jun 6, 2019 at 11:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .