1

Hardware setup (computer, etc)

  • Ubuntu server 18.04.1
  • Serial To Usb Converter with 8 ports

Python version

  • 2.7.15r1

Python program description

When the program starts to create some threads:

  1. Create one thread for the Modbus server.
  2. Run 1 thread for each serial port connected (/dev/ttyUSBn) and start read the data.

Problem explanation

When I run the script using the normal command (python2.7 myProgram.py) it work, so the modbus server start and I can read the value, and I can also see the usb-serial convert blink on the TX-RX leds. If I check the readed data they are correct, so the program is working properly.

The problem come out when I set up a crontab job that run my python script!

The modbus server start properly, but I can't see the usb-serial converter leds blink and the python program don't print the readed data. That means the program is not working on the "serial" side.

To create the job I has used the following commands:

  1. crontab -e
  2. selected nano (default option)
  3. added at the end of the file the cron command: @reboot /usr/bin/python2.7 /myProgram.py

I can't figure out where the problem is, the program is not catching the exception and the process is still running until I stop it manually. If I stop it and run it manually after that it start and work properly.

To help you:

I have also tried to run it using **systemctl**, the problem is the same. At boot the service start and if I check it I can read: Active(running), but the software is not reading from the serial port.

The questions are:

  • How can I solve it?
  • There is something wrong with the crontab job?
  • Maybe crontab job can't access the /dev/ directory? How can I solve this?

I'm very confused about that, I hope the question is properly created and formatted.


EDIT 30/11/18:


I have removed the crontab command, and create a service to run the program using this procedure.

If I run the command: service supervision start I can see that the process is running correctly and on htop I have only 4 processes.

htop output

service status output

In this case, the program is not reading from the serial port, but the modbus server is working. You can see that I have just 4 processes and the cpu load is too high.

If I run it manually with the command: python2.7 LibSupervisione.py

The output of the htop command is: outupt of working program

Here you can see that I have more processes, 1 for each thread that I create and the load on the cpu is properly distributed.

Carlo Zanocco
  • 1,967
  • 4
  • 18
  • 31
  • Change to `... myProgram.py >>/tmp/myProgram.log 2>&1`, to get the error message and read [crontab-not-running-my-python-script](https://stackoverflow.com/questions/12534135/crontab-not-running-my-python-script) – stovfl Nov 29 '18 at 20:09
  • Add this `#!/usr/bin/env python` shebang on top of your code, and set `chmod 755` to your code, but the best way is that you create a service from your code, I using from [this procedure](https://stackoverflow.com/a/51242883/3702377) for that. – Benyamin Jafari Nov 29 '18 at 20:32
  • @stovfl I have tryed to add the `>>/tmp/myProgram.log 2>&1` in my crontab command, but nothing where printed in the file. As I told the problem is non that the cron job isn't running, but the problem is that it run, start just a piece of program. Thanks anyway for the help! – Carlo Zanocco Nov 30 '18 at 07:22
  • @BenyaminJafari I have tryed to create the service using systemctl, I'll try with your guide! At the top of the file I alredy have `#!/usr/bin/python2.7` and I have updated the permission of the folder to **777** using this command: `chmod 777 /programFolder/ -R` – Carlo Zanocco Nov 30 '18 at 07:26
  • @CarloZanocco Could you run your script using a service? – Benyamin Jafari Nov 30 '18 at 09:00
  • @BenyaminJafari I have tested it now. The service start correctly but nothing change. I have tryed to run it manually and it work, if I check the processes with `htop` I can see that there a many processes, 1 for each thread(15 processes), and the core are correctly used by the program! If I run `htop` when the program start from the service, the program use just 1 core and I can see only 3 processes so 3 threads running. – Carlo Zanocco Nov 30 '18 at 09:17

2 Answers2

1

If you could run your code with the service like this: sudo service <service-name> start and get a good status using sudo service <serivice-name> status, you can test it in crontab -e like this (run every 5 minutes for test):

*/5 * * * * service <service-name> start
*/10 * * * * service <service-name> stop

Then using @rebote after with the above test.


OR:

Finally, if you want to run your code/service at the system startup, do it instead of cron jon:

Edit the rc.local file with an editor with the sudo permission, then:

#!/bin/sh -e

# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.


service <service-name> start

exit 0

[NOTE]:

This is the procedure of creating a service from your code.

Benyamin Jafari
  • 27,880
  • 26
  • 135
  • 150
  • The problem is still here. The process is running correctly in any case, I always have a good status. But the problem is that the program not work the same as when I run it manually! Using `service test start` it run, I have a good status, but the serial port is not reading in any case. And the server Modbus is working correctly. If I run the code manually with `python2.7 myProgram.py` it work and read from the serial port. – Carlo Zanocco Nov 30 '18 at 09:54
  • I have added more info to the question, check the edit please – Carlo Zanocco Nov 30 '18 at 10:32
  • I did it, please put on your code for better sense. – Benyamin Jafari Nov 30 '18 at 10:35
  • I can't put on the code, I can create a sample code to share with you. But why you need it? The code is working correctly, as I told if I run it not as service it work. – Carlo Zanocco Nov 30 '18 at 10:37
  • Don't use this, why start initd from system when you can call it directly. – comrad Nov 30 '18 at 10:56
  • @comrad Because in the title of question mentioned "running program not working in crontab", so to overcome it, service is a better way rather than direct running, because it produces `start`, `restart`, `stop` and `status` ... – Benyamin Jafari Nov 30 '18 at 12:24
  • @CarloZanocco OK, no problem if you don't want to put on your code. Is your problem that when you run the code by serivce, usb-serial led does not blink? Did you try add the root permision on your usb port using `sudo chmod 777 /dev/ttyUSB*`? – Benyamin Jafari Nov 30 '18 at 12:35
1

Your script probably requires a Console or some Environment variables, but in a systemd started process you dont have these automatically.

The easiest way would be to prepend /usr/bin/bash -c "your command" in your System unit in the field ExecStart to enable a Shell like Environment likle this:

ExecStart=/bin/bash -c "/usr/bin/python2.7 /myProgram.py" 

WorkingDirectory=yourWorkingDir 

Why do you Need to use cron? Use a systemd timer instead.

Carlo Zanocco
  • 1,967
  • 4
  • 18
  • 31
comrad
  • 105
  • 7
  • I don't need to use cron, I have tested it, because the problem persist with systems, systemctl, service and cron command. I have created a service and the problem persist. The program **START** but is not reading from the serial port, but the modbus server is working. – Carlo Zanocco Nov 30 '18 at 10:06
  • Did you start your program with a prepended Shell? Like bash? I know this problem from own experience. – comrad Nov 30 '18 at 10:55
  • What it means? Sorry but I don't know what you mean with prepended Shell.. I log in to the remote computer using ssh root@ip, after that I use the shell of the Ubuntu Server computer – Carlo Zanocco Nov 30 '18 at 10:58
  • you are right. I understand what you mean! But in the script I have to read one config file. I have the path that is not absolute! In the program I have : ` path = "Utility/config.txt" `, but this is wrong, because the folder is in another folder, so the path is not absolute. The correct way is to use: `path = "/Monitoraggio/Utility/config.txt"`. So I have to start from the `/` directory! – Carlo Zanocco Nov 30 '18 at 11:48
  • Try to Change the systemd unit to: `` ExecStart=/bin/bash -c "/usr/bin/python2.7 /myProgram.py" WorkingDirectory=yourWorkingDir `` – comrad Nov 30 '18 at 11:55