How to create a systemd file exchange service

How to create a systemd file exchange service

We are going to explore how basic Linux utility functions like curl, logger and inotifywait will allow us to define a basic file exchange service

In this article, we are going to go over an example for defining a systemd service that will allow the user to exchange files with another machine. It will work by specifying a couple of folders for sending and receiving files. These files will be exchanged using the File Transfer Protocol, commonly known as FTP, which is a standard network protocol used for transferring files from one host to another over a TCP-based network, such as the Internet. An FTP service serves as an intermediary platform that facilitates the seamless movement of files, providing a reliable and structured way to exchange data.


The first step will consist of installing the dependencies required for executing the service. These will be curl for sending the file using FTP, and pure-ftpd as FTP server.

sudo apt install curl
sudo apt install pure-ftpd
sudo apt install inotify-tools

Send service

The send service will consist of a script, which takes five arguments:

  • out_tray: this is the folder where the user has to put the files to be sent to the destination host.

  • ftp_user: user used for the FTP connection.

  • ftp_password: password for the user of the FTP connection.

  • ftp_host: destination host for the FTP transfer.

  • ftp_folder: folder within the destination host where the files are going to be copied.

This script monitors the out_tray folder checking for new files using the inotifywait utility. Once a new file is detected, it sends the file to the FTP destination using curl. It also uses the logger utility to print traces about the execution of the script.

if [ $# -ne 5 ]; then
  echo "Usage: <out_tray> <ftp_user> <ftp_password> <ftp_ip> <ftp_folder>";

while file="$(inotifywait -q -e move --format %f $1)";
  logger "[`basename "$0"`] Sending file $file"
  curl -T $1/$file ftp://$4/$5/$file --user $2:$3
  rm $1/$file;
  logger "[`basename "$0"`] Sent file $file"

The next step is to define a systemd service that will call the script.

Description=Send Service

ExecStart=/usr/local/bin/transferor/ /usr/local/bin/transferor/outTray al al /usr/local/bin/transferor/inTray


Receive service

The receiving service will follow a similar approach. It will be composed of the script, which takes two arguments:

  • in_tray: folder where files sent through FTP from the source host are received.

  • script: script file to be executed to process the files received in the in_tray folder.

This script also monitors a folder using the inotifywait utility. Once a new file appears in the in_tray folder, it runs the script specified as an argument to process the received file. As the did, it uses the logger utility to print traces about the execution of the script.

if [ $# -ne 2 ]; then
  echo "Usage: <in_tray> <script>";

while file="$(inotifywait -q -e close_write --format %f $1)";
  logger "[`basename "$0"`] Received file $file"
  source $2 "$1/$file";
  logger "[`basename "$0"`] Processed file $file"

For example, we can define an processing script that just echoes the content of the received file.


cat $1

After coding these two scripts, we can define the systemd service that will execute the script.

Description=Receive Service

ExecStart=/usr/local/bin/transferor/ /usr/local/bin/transferor/inTray /usr/local/bin/transferor/



Once we have all the scripts and services defined, we can deploy them to the proper folders and set them up to be run as systemd services.



echo "Creating directory $TARGET"

sudo mkdir $TARGET
sudo mkdir $TARGET/inTray
sudo chown al:al $TARGET/inTray
sudo mkdir $TARGET/outTray
sudo chown al:al $TARGET/outTray

echo "Copying files into $TARGET"
sudo cp app/ $TARGET
sudo cp recv/ $TARGET
sudo cp recv/recv.service $TARGET
sudo cp send/ $TARGET
sudo cp send/send.service $TARGET

echo "Installing services"
sudo ln -s $TARGET/recv.service /etc/systemd/system
sudo systemctl enable recv
sudo ln -s $TARGET/send.service /etc/systemd/system
sudo systemctl enable send

echo "Done"

After deploying the scripts and services, we have to reboot the machine. And after that, we can check the status of the defined services.

sudo reboot
sudo systemctl status recv
sudo systemctl status send

Testing the example

At this point, we should have both services up and running. Therefore, we can do a quick test to check that they work as expected. To do so, we just have to copy a test file into the out_tray folder, and we will see the content of that file in the log messages of the logger utility.

echo "test" > test.txt
sudo mv test.txt /usr/local/bin/transferor/outTray

journalctl -f


In this article, we have seen a simple way of defining a systemd service that allows you to easily send files between hosts, just by copying them to the outbound folder. And allows you to run a script to process the received file in the destination host. That way you could automate the distribution and processing of files among multiple machines. Obviously, this example is not suitable for production code. But it allows you to get a grasp of how basic utilities like inotifywait, logger, curl and the definition of systemd services work.