3

I thought that running commands on raspberry pi on boot was the easiest thing in my project. But it seems that it is complex enough not to work.

I've searched a lot on the internet on a simple objective that I couldn't solve yet. All I want to do is to launch chromium normally (not in full-screen mode or any other setting). I also need to start node.js server on boot.

I've followed this website but that didn't help at all.

I kept on seeing gnome-scheduler that is a GUI application that is supposed to run commands on boot. Now this package is deprecated, but I found previous versions at launchpad that I downloaded but I know nothing about how and where to put the downloaded files in order to work.

In the convenience of what I am looking for, I made a python script that is supposed to open a URL in chromium. And the issue should be simplified if I just put the two commands :

  • Run Python (Open URL in Chromium)
  • Start listening on Node.js server

But after using all the methods that were stated at the above tutorial none seem to work. Maybe the problem is that when the raspberry pi is booting other services doesn't seem to load completely.

OS: Raspbian Buster

The method I am working on is SYSTEMD:

import webbrowser
import time

time.sleep(30) #To debug if latency is the problem
webbrowser.open('https://www.google.com')
print("Hey There Log File! I made it till here!")

But this python script doesn't run because when I check the log file it is empty neither anything is printed nor the browser opens why?

Edit1: Write a new Unit file sudo nano /lib/systemd/system/sample.service

Inserting code:

[Unit]
Description=My Sample Service
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python3 /home/pi/sample.py

[Install]
WantedBy=multi-user.target

In order to store the script’s text output in a log file, you can change the ExecStart line to:

ExecStart=/usr/bin/python3 /home/pi/sample.py > /home/pi/sample.log 2>&1

The permission on the unit file needs to be set to 644 :

sudo chmod 644 /lib/systemd/system/sample.service

Now the unit file has been defined we can tell systemd to start it during the boot sequence :

sudo systemctl daemon-reload
sudo systemctl enable sample.service

Then reboot Raspberry Pi.

Edit2:

Thanks to @JayBuckel and his question: Issues when trying to open Chromium at a certain URL on boot. I have made some progress. All I had to do was to insert my command @chromium-browser https://www.google.com just before the @xscreensaver -no-splash line and Chromium starts at boot and directs to the relevant URL.

All I have to do now is to run node server.js command somewhere.

Edit3:

Currently, I am reading about how to Run node.js service with systemd?

Take a look at this for running a node server continously using pm2 https://raspberrypi.stackexchange.com/a/94850/90033

  • This tutorial worked well to launch scripts on startup: instructables.com/id/… – raspberrypitime Oct 5 at 14:08
  • Welcome -- you need to provide more information: 1) "when I check the log file it is empty " What log file? The code you have posted prints to standard output which means it is probably discarded. 2) "The method I am working on is SYSTEMD:" Then please include the service file you created. – goldilocks Oct 5 at 17:00
  • time.sleep(30) #To debug if latency is the problem It will be if the program does not properly background itself; it will be killed at some point because of that. – goldilocks Oct 5 at 17:02
  • @goldilocks The information you want me to give is the same as in the tutorial. And I used time.sleep(30) after realizing that the code doesn't work. But it is a good point of view. Thanks. – Youssof H. Oct 5 at 17:21
3

If you're expecting a GUI browser to open, the DISPLAY environment variable may need to be explicitly set so that the browser the webbrowser module opens knows where to show itself. Otherwise it would likely not start at all and instead crash, not finding a valid GUI. For a systemd.service, you would do this by adding the line

Environment=DISPLAY=:0

to the [Service] section of the file before the ExecStart. You may instead need to specify the XAUTHORITY environment variable, as described here due to the service running as a different user. In which case the line to add would be

Environment=XAUTHORITY=/home/pi/.Xauthority

where 'pi' is the username the startup X instance runs as.

The reason you may not be seeing the printed log statement is a crash out of the script, the webbrowser has started a command line only browser, like links, and is waiting, or the GUI has not yet started when the python script finally gets to launching the browser.

If the sole purpose of the python script is to open a browser however, I would recommend directly starting the browser instead of relying on a Python script to do that. If you are concerned about the browser starting after node.js or the GUI, systemd service dependencies can be used to ensure it starts after those two using, e.g., Wants=mynodejs.service lines, see here for more details.

  • 1
    The log print isn't happening because the OP used shell redirection >, 2>&1 in the ExecStart=command, which never invokes a shell (unless that's an explicit part of "command"). – goldilocks Oct 5 at 18:33
  • Hey @Fred what do you mean by "directly starting the browser"? Do you mean by that to run this command chromium-browser https://www.google.com somewhere on boot? If that was your purpose then now I can run both commands at once node myServer.js do you have any hints? – Youssof H. Oct 6 at 4:37
  • @YoussofH. Yes, so instead of ExecStart=/usr/bin/python3 /home/pi/sample.py use ExecStart=chromium-browser https://www.google.com, and then create a second node.service file to start node.js with ExecStart=node myServer.js. Add Wants=node.service and After=node.service to the chromium service's [Unit] section. – Fred Oct 6 at 8:22
3

In order to store the script’s text output in a log file, you can change the ExecStart line to: ExecStart=/usr/bin/python3 /home/pi/sample.py > /home/pi/sample.log 2>&1

This is wrong, although I notice there are a few Raspberry Pi oriented tutorials that claim it will work.

It will not work because > (and 2>&1) are POSIX shell operations, but you are not invoking this via a shell (as you would from the commandline). It's executed by systemd and all that stuff will be passed to the command (/usr/bin/python3) as arguments in addition to the script path, and those garbage arguments probably cause python to exit with an error.

You need to use these directives as explained in man systemd.exec:

StandardOutput=file:/home/pi/sample.log 
StandardError=file:/home/pi/sample.log 

You should test this with:

sudo systemctl start sample.service
sudo systemctl status sample.service

The last command is important because the first one alone may not provide you with all the relevant information. If you do this with sample.service as is (ie., don't fix the redirects), you will probably see the python error output.

Note that if you modify the service file after using systemctl enable you should run systemctl daemon-reload. However, you can test it directly without enabling it.

  • Thanks for the answer and the notes. After completing the above steps the sample.log's text is replaced every time with the debugging statement "I made it till here..." so logs are not appending. Anyway the URL didn't open in chromium do you have any idea. I suggest that @Fred was surrounding the issue by setting the display environment. What do you think? – Youssof H. Oct 6 at 4:43
  • Although the log statement appeared which means that sample.service has executed the python script. I have noticed that I have used chmod 644 file that has permissions to read and write instead of using chmod 755 file that has permissions to read, write, and execute the service. Is this related to the problem? Thanks. – Youssof H. Oct 6 at 5:23
  • 1
    I don't understand what you are applying the chmod to, but none of the files involved in the discussion here need to be exectuable (as long as the script is executed via /usr/bin/python3). The service file does not need to be executable. The log does not need to be executable. – goldilocks Oct 6 at 17:40
  • 1
    Sorry for the flowery stuff! My point was, if you are still trying to solve this problem a day later, it will probably be worthwhile to spend an hour or two implementing your own logging. – goldilocks Oct 6 at 19:45
  • 1
    @Ingo Please don't show people that ExecStart line with bash, lol. It will only make things worse; it's the kind of thing that if you think of it yourself, great, but passing it on is prone to cargo cult practices that end up screwed up in blogs (such as the OP's reference) >_<. This is especially true when there is essentially a better/more formal way to do it (via Standard..). – goldilocks Oct 7 at 13:08
3

Just haven't a monitor by hand so I can't test it but here are some ideas how it could work with reference to this accepted answer How to make a service to run a python script which includes browser automation.

First of all we have a graphical output so the multi-user.target isn't enough. It is only for the text console. We have to use the graphical.target. Then I would not use a python script, so the unit could look like this:

[Unit]
Description=My Sample Service
Wants=graphical.target
After=graphical.target

[Service]
Environment=DISPLAY=:0
#User=pi
#WorkingDirectory=/home/pi
#ExecStartPre=/bin/sleep 30
ExecStart=/usr/bin/chromium-browser https://www.google.com
ExecStartPost=/bin/echo "Hey There Log File! I made it till here!"

[Install]
WantedBy=graphical.target

There are some commented lines for testing. I don't believe that you need a sleep. The output to stderr and stdout, here that echo, you will find in the journal:

rpi ~$ journalctl -b -e
  • Sadly your answer didn't work for me even though I looked at the related question. Neither chromium is opened nor the log is written. – Youssof H. Oct 7 at 17:58
  • @YoussofH. What do you get with systemctl status sample.service? It MUST tell you something about the service, even if it is dead. – Ingo Oct 7 at 22:18
2

I had an issue like that with one of my Python projects, where I needed a Bash script with the steps to run my program to run not only after the Raspberry Pi boots, but also after the GUI loads. What worked for me was following the instructions in one of the posts in the "How to launch programs on LXDE startup" topic in the raspberypi.org forums, depending on the version of Raspbian doing

  • For Raspbian Wheezy with the LXDE GUI desktop: sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
  • For Raspbian Jessie or Raspbian Stretch, with the Pixel GUI desktop: sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart

to edit the autostart file, adding the line

@/home/pi/the_name_of_my_script

(because I had put my script in /home/pi :-)) to the end of the file, and saving it.

  • Note that /etc/xdg/lxsession/LXDE-pi/autostart is there in Jessie, Stretch and Buster too. It's not obsolete in any way, like one may assume reading your answer. – Dmitry Grigoryev Oct 7 at 8:17
  • @DmitryGrigoryev Although I have Raspbian Buster the recommended command didn't work for me any ideas? – Youssof H. Oct 7 at 18:14
  • @YoussofH. Usually that happens because you have both files, in which case /home/pi/.config/lxsession/LXDE-pi/autostart gets priority treatment. If you only ever login as one user, it doesn't matter which one you use. – Dmitry Grigoryev Oct 8 at 6:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.