2

The following Python script named "tst_script.py" writes in a file. It works when it is launch via command line but fails to create the file when lauch via a systemd service.

#!/usr/bin/python
#-*- coding: utf-8 -*-

import time

if __name__ == '__main__':
    with open('test_file', 'a') as fd:
        while True:
            for i in range(10):
                fd.write('test' + str(i) + '\r\n')
                time.sleep(3)
            break

The service script named "tst_script.service" is the following:

[Unit]
Description=Python test script
[Install]
WantedBy=multi-user.target
[Service]                                                                                             
Type=simple                                                                                           
ExecStart=/usr/bin/python -O /home/gilles/tst_script.py

The service script is copied in "/lib/systemd/system" folder and activated by:

sudo systemctl daemon-reload
sudo systemctl enable tst_script.service

We check that the service is installed and enabled by: sudo systemctl status tst_script.service

The result is:

tst_script.service - Python test script
   Loaded: loaded (/lib/systemd/system/tst_script.service; enabled)
   Active: inactive (dead) since ven. 2018-03-02 13:35:00 CET; 16min ago
 Main PID: 10565 (code=exited, status=0/SUCCESS)

and we launch the service by: sudo systemctl start tst_script.service

We check that the script is running: sudo systemctl status tst_script.service

The result is:

tst_script.service - Python test script
   Loaded: loaded (/lib/systemd/system/tst_script.service; enabled)
   Active: active (running) since ven. 2018-03-02 13:51:17 CET; 1s ago
 Main PID: 10738 (python)
   CGroup: /system.slice/tst_script.service
           └─10738 /usr/bin/python -O /home/gilles/tst_script.py

And after 30 seconds, we check that the process is completed:

tst_script.service - Python test script
   Loaded: loaded (/lib/systemd/system/tst_script.service; enabled)
   Active: inactive (dead) since ven. 2018-03-02 13:51:47 CET; 3s ago
  Process: 10738 ExecStart=/usr/bin/python -O /home/gilles/tst_script.py               (code=exited, status=0/SUCCESS)
 Main PID: 10738 (code=exited, status=0/SUCCESS)

but, as a result, the file "tst_file" doesn't exist...

I googled but don't find any answer who solve my problem. The closest answer I found is running python script as a systemd service.

Have you any idea to solve this problem ?

Gilles
  • 23
  • 1
  • 4
  • 3
    Where are you looking for the file `tst_file`? Can you find it under the root directory `/` (which is the default working directory of commands executed by `systemd`)? – Cong Ma Mar 02 '18 at 13:38
  • Program that are run by system, should not expect a particular environment. Use absolute path of your file. Do not use -O (but just before when installing the package). – Giacomo Catenazzi Mar 02 '18 at 13:39
  • 1
    @Cong Ma: It's time for me to take some rest. ;-) I didn't think to look for the file in the root directory. It was there. Thank you for you fast answer ! – Gilles Mar 02 '18 at 13:52
  • [Documentation on setting working directory](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#WorkingDirectory=) – Cong Ma Mar 02 '18 at 13:55

1 Answers1

3

As Cong Ma mentioned in the comments, the most obvious problem is that you are probably looking in the wrong place. In your code you have the output file as: with open('test_file', 'a') which when you are testing this script appears in the same folder as the script.

The problem is, that Python does not interpret file_name as /path/to/python/script/file_name but instead reads a relative path as relative to the present working directory. If you are kicking off from systemd, your present working directory is not the same as where the script is located.

You can handle this by configuring your service, but easier in this case is to just provide an absolute path to the output file:

import time

if __name__ == '__main__':
    with open('/home/gilles/test_file', 'a') as fd:
        while True:
            for i in range(10):
                fd.write('test' + str(i) + '\r\n')
                time.sleep(3)
            break

If you'd rather fool around with the service, you can change the working directory of systemd. This info might be helpful: Changing Working Directory of systemd service

Lost
  • 998
  • 10
  • 17