Execute script on start-up

  • I am trying to execute a script when my Raspberry Pi boots up. I would like the web browser to open up automatically.

    I have tried to find a simple solution, (like dropping my script in some "startup" directory or something similar) but I am not seeing anything like that.

    I have looked into Upstart, but I'm struggling to grasp how that works. Any scripts I've tried have not worked when I test them out.

    What operating system are you running? In FreeBSD, which I'm using on my Pi, you can add startup scripts to /usr/local/etc/rc.d/, or just add things to /etc/rc.local. Different Linux distros have different recommended methods. If you're running X on it, then you should might look into adding things to your `.xinitrc` or `.xsession` file.

    More information about the X startup process can be found over here.

    **Please note** the accepted answer here has some caveats and technically *does not* start anything at boot except under specific conditions. Read it carefully.

    You are asking for a script that runs when you log in, not when the pi boots or at start-up. Two _very_ different things, and the title is skewing the google search results.

    if you want to autostart a **node.js** script at boot, use pm2. it's designed specifically for that; for running scripts at boot, tracking their stdout and stderr in log files, restarting scripts, etc.

  • syb0rg

    syb0rg Correct answer

    7 years ago

    For running Midori on startup, take a look at this tutorial. For DIY solutions, read on.


    You can add your script executable command to the bottom of .bashrc that will run your script every time open a terminal (or run a new instance of bash).

    1. Make sure you are in the pi folder:

      $ cd ~
      
    2. Create a file and write a script to run in the file:

      $ sudo nano superscript
      
    3. Save and exit: Ctrl+X, Y, Enter

    4. Open up .bashrc for configuration:

    .bashrc is NOT intended to run scripts.

    It is run each time a non-login interactive shell is started and is used to configure the shell.
    ~/.bashrc: executed by bash(1) for non-login shells.

       $ sudo nano .bashrc
    
    1. Scroll down to the bottom and add the line: ./superscript

    2. Save and exit: Ctrl+X, Y, Enter


    If you are looking for a solution that works on bootup to the console, take a look at this link. Basic rundown:

    1. Create a file for your startup script and write your script in the file:

      $ sudo nano /etc/init.d/superscript
      
    2. Save and exit: Ctrl+X, Y, Enter

    3. Make the script executable:

      $ sudo chmod 755 /etc/init.d/superscript
      
    4. Register script to be run at startup:

      $ sudo update-rc.d superscript defaults
      

    If you want a script to run when you boot into the LXDE environment, you could take a look at this Raspberry Pi forum post:

    1. Navigate to ~/.config/lxsession/LXDE-pi

    2. Open the autostart file in that folder:

      $ sudo nano autostart
      
    3. Add @midori on a new line. If you want to run something like a python script, put something like @python mypython.py on a new line. Running a script file would be @./superscript, but for some reason the script runs in an infinite loop (perhaps this will stop that).

    4. Save and exit: Ctrl+X, Y, Enter

    5. Restart your Raspberry Pi into the LXDE environment.

    The tutorial on setting up Midori on startup was just what I was looking for. Not sure why there are so many ways to do such a simple thing, but I'm glad it's working now.

    @syb0rg The run at login part works like a charm (+1) if I log in via ssh, but not when the lxde desktop session starts. is there a way to do that ?

    @GeorgeProfenza When you do `$ sudo startx`?

    @syb0rg Using `raspi-config` raspian is configured to boot with the graphical interface. I'm not sure how that's done behind the scenes(if sudo startx is executed or simply startx) because I see the graphical interface, but the script does not run. However, when I ssh into the RPi the script starts.

    @GeorgeProfenza I edited in a whole new section dedicated just for you :)

    @syb0rg So close :) LXDE/autostart method works, although running @./superscript (in my case ./svnc where I launch tightvncserver) has a weird side effect: the script runs over and over again and I get multiple vnc server launched continuously drowning the system. As a safer solution, after reading this post I've installed avahi so now it's easier to log in via ssh, and launch the vnc server then. It would be handy to know to to avoid the script lanuch loop with the LXDE/autostart file method

    @GeorgeProfenza I've edited in a link to shut down a script when it's done, maybe that will help.

    What would the code be if you just want to run ONE command when the RPi starts? I am using the middle method and to do it normally I would type: `$ sudo /opt/jdk1.8.0/bin/java -Xms256M -Xmx496M -jar /home/pi/spigot.jar nogui`

    @AnnonomusPerson Put that command in a script then run the script at startup.

    Just wanted to point out that the pyhton script will run, but if there are any errors, it will just be somewhere in the background using the /etc/xdg/lxsession/LXDE/autostart method. using .barshrc will reveal errors as well, but it's really important to make sure the script is tight in the first place (found that out the hard way :) )

    @GeorgeProfenza So it is a python script?

    @AnnonomusPerson I intended to launch my python script on LXDE startup, yes, but the methods presented above work for launching a bash script or any other app installed on the RPi

    I am getting following message, after adding script in .bashrc, when ever I opens my lxterminal `bash: ./main: Permission denied`

    Part of this is I believe outdated -- the `/etc/xdg` path should be `/etc/xdg/lxsession/LXDE-pi`; edited to reflect this.

    **`.bashrc` is not read when the system boots or when a user logs in**, only when opening a new terminal (and it's read each time the user opens a new terminal). I'm baffled that this answer got so many upvotes: **the first part is plain wrong**. The third part is correct to execute a GUI program.

    @Gilles A new terminal is opened up on boot... how else would you interact with the OS?

    @syb0rg Through a GUI. And you need to log in first if autologin isn't enabled.

    the `.bashrc` trick only works if you open a terminal window (and every time you open another terminal window). In contrast, if you just wait until the graphical shell launches, nothing happens.

    What if my python script needs to be run as sudo?

    How can I authenticate the root user on bootup, not login?

  • The way that I've seen most people do it (have a look on the Raspberry Pi forums), and have done myself with success is using /etc/rc.local.

    All you need to do here is put ./myscript in the rc.local text file. If it's in python, put python myscript.py.

    This literally is "a simple solution, (like dropping my script in some "startup" directory or something similar)"- maybe search on the forums when you're having questions as well, this solution came up on the first 4 results of a google search!

    FYI the rc.local by default has various comments about the script doing nothing and needing executable bits changed. This is not true just enter the command for your script before the exit 0 and it will run on startup. Make sure your script exits of runs in the background or it will block the login prompt. Yes, thats what I did.

    @rob Do you mean they suggest the script to be set as executable? This is mitigated in the question by running the script by the command `python myscript.py`. If you want to chmod +x it and add `#! /bin/python`, you can run the script by doing `$pathtofile/myscript.py` where `$pathtofile` is `.` if you're in the same directory or the absolute or relative path to the file.

    @JFA run "ls -l /etc/rc.local" that will show if that file is executable or not, look for the "x" in the list of permissions.

    @rob yes I understand how that works. I was trying to clarify your post.

    That's no good for a GUI program such as a browser. `/etc/rc.local` is only to start system services (programs that don't have a user interface).

    Although this works perfectly on my Pi 1 B+, it won't work on my Pi 3 for some unknown reason, running the exact same script (that will run manually on both). I'm not sure why it's not working on the Pi 3.

    Fixed (source: http://elinux.org/RPi_Email_IP_On_Boot_Debian) I added `sleep 30` after the last comment in `/etc/rc.local`, before any of the script code, and now my script runs fine.

    What about scripts that need sudo? ie. noip?

    @Gilles I'm looking exactly for a GUI program. Do you have a suggestion? (I would like to start Kodi)

    @ErickM.Sprengel Use one of the correct answers on this thread, such as this one.

    simply doing `python myscript.py` didn't work for me. Had to do: `bash -c '/usr/bin/python3 /home/pi/myscript.py > /home/pi/myscript.log 2>&1' &`

  • Add it to the crontab

    The crontab runs commands at defined times.


    Edit the file:

    sudo crontab -e
    

    Add line to file (here a python script):

    @reboot python3 /home/pi/Desktop/exemple.py &
    

    To be a little nitpicking here, technically it's not crontab that runs the command, but anyways. With regard to the listed line to add, it is advisable to put full paths for the commands defined here (in this case the full path to `python3`), see here

    This is the method I've always used due to it's simplicity. +1

    That's no good for a GUI program such as a browser. `/etc/rc.local` is only to start programs that don't have a user interface.

    After spending way to much time trying to get it working with rc.local and init.d and all sorts of other stuff.. this worked straight away! Thanks allot!

    this doesnt work for some reason in rpi os

    Seems like it works fine, but only on some of my Raspberry Pis. It's consistent though. The ones it does work always work; the ones that don't work, don't work always.

    AFAIK the cron @reboot only works for, guess what?, reboots. I mean, it doesn't work when turning on from an off state for example. This is the reason I tend to avoid this option.

    Where is the information stored? It seems to be in `/tmp`. That can not be(?).

  • Autostarting xorg apps

    If the script you want to start requires an xorg session then you might try following the freedesktop autostart spec which might or might not work depending on which desktop environment you are using.

    Alternatively, you can target your specific desktop environment as described at https://wiki.archlinux.org/index.php/autostarting.

    Running a script as a systemd service

    If your script fits the description of a daemon or a 'service', and your system is running systemd which is the case for raspbian and most modern linuces, then you can configure your script to run as a systemd service — this provides granular control over the lifecycle and execution environment, as well as preconditions for (re)starting the script, such as the network being up and running. It is also possible to configure the service restart in case of failure (Restart=always, and delay between restarting e.g. RestartSec=10).

    For system-wide use create your systemd unit file under /etc/systemd/system, e.g. with vim /etc/systemd/system/autossh.service:

    [Unit]
    Description=Autossh keepalive daemon
    ## make sure we only start the service after network is up
    Wants=network-online.target
    After=network.target
    
    [Service]
    ## use 'Type=forking' if the service backgrounds itself
    ## other values are Type=simple (default) and Type=oneshot
    Type=forking
    ## here we can set custom environment variables
    Environment=AUTOSSH_GATETIME=0
    Environment=AUTOSSH_PORT=0
    ExecStart=/usr/local/bin/ssh-keep-alive.sh
    ExecStop=/usr/bin/killall -9 autossh
    ### NOTE: you can have multiple `ExecStop` lines
    ExecStop=/usr/bin/killall ssh
    # don't use 'nobody' if your script needs to access user files
    # (if User is not set the service will run as root)
    #User=nobody
    
    # Useful during debugging; remove it once the service is working
    StandardOutput=console
    
    [Install]
    WantedBy=multi-user.target
    

    See also:

    Now we are ready to test the service:

    systemctl start autossh
    

    Checking the status of the service:

    systemctl status autossh
    

    Stopping the service:

    systemctl stop autossh
    

    Once you verified that the service works as expected enable it with:

    systemctl enable autossh
    

    NOTE: For security purposes systemd will run the script in a restricted environment, similar to how crontab scripts are run, therefore don't make any assumptions about pre-existing system variables. Use the Environment keys if your script needs specific variables to be defined. Adding set -x at the top of your bash script and then running systemctl status my_service might help identify why your script is failing. As a rule of tumb, always use absolute paths for everything including echo and cat, or explicitly define your $PATH.

  • I want to throw in my two cents, even though this is an old question but commonly asked to do simple thing - autostart. I tried all the suggested solutions in all the answers for this question. NONE of them worked for me. I am using Raspberry PI Model 2 with Raspbian.

    The only way I could get my application to autostart successfully is through a script as follows. I say successfully because my application started as expected without having any issue like starting with wrong work path.

    1.Create an empty file with extension .sh and name it whatever you want.

    2.Copy and Paste the following EXACTLY except change "your application name" to the script name that you just created.

     #! /bin/sh
    
     ### BEGIN INIT INFO
     # Provides:          noip
     # Required-Start:    $remote_fs $syslog
     # Required-Stop:     $remote_fs $syslog
     # Default-Start:     2 3 4 5
     # Default-Stop:      0 1 6
     # Short-Description: Simple script to start a program at boot
     ### END INIT INFO
    
     #change /direct/path/to/your/application to the path your application is in.
     cd /direct/path/to/your/application      # example cd /home/pi/myprogram/
    
     #change YourProgramExactName to Exact name of your program that you want to auto start
     ./YourProgramExactName
    
     exit 0 
    
    1. Then, save the script file within your application folder

    2. Then, open /home/pi/.config/autostart folder. It might be different in your case. Just open your home folder and enable view hidden folders. open .config/autostart. If you don't see autostart folder, then create a folder called autostart within .config folder.

    3. within autostart folder you will need to create a shortcut to your script file that you created as follows. Create an empty file with extension .desktop.

    4. Copy and paste the following in the empty desktop file except you will need to change Comment, Name, Exec, Path and Icon field's value.

      [Desktop Entry]
      Comment=
      Exec=/path/to/Your/application/Name-of-the-script-file (.sh)
      Icon=/Path/to/Your/application/Icon/IconName
      Name=YourApplicationEXACTNAME
      Path=/Path/to/Your/Application-ONLY
      Type=Application
      
    5. Save and close the file after changing all the necessary fields. You are done. Just test it out.

    Technically this script is run by the system rather than by a specific user - so perhaps your __application__ better belongs in `/usr/local/bin/ApplicationName`...?

    @SlySven "the system" is a specific user.

    Is it run as root (UID = 0) or the pi user (UID ~ 500 or 1000 IIRC) - if it is run as root or another *system* UID (less than 500) then it is *traditionally* good practice to store the script file (or any that it depends on) on the root device so that should there be a problem with any other device (e.g. `home` if that is a separate device) there will not be a problem with the script (or an executable) file being unavailable when the system fails back to a single user `/bin/sh` shell! Nowadays the `systemd` way is to mount both `/` and `/usr` before PID 1 is started...

  • I also had trouble with this. On the Raspberry Pi3 running Raspbian this is what I did:

    1. Create a startup shell script in your root directory (I named mine "launch"):

    sudo leafpad launch.sh

    1. Save the file
    2. Edit the LXDE-pi autostart file

    sudo leafpad /home/pi/.config/lxsession/LXDE-pi/autostart

    1. Add this to the bottom of that file

    ./launch.sh

    1. reboot
  • On the Raspberry Pi3 running Raspbian Stretch this is what I did:

    Edit the LXDE-pi autostart file

        sudo nano /home/pi/.config/lxsession/LXDE-pi/autostart
    

    Add this to the bottom of that file

        @sudo python3 /path/to/your/script.py
    

    save & reboot

  • Method 1:

    To launch a command automatically on login, put the command into a file named

    .bashrc
    

    in the user directory (for example /home/pi)

    .bashrc is NOT intended to run scripts.

    It is run each time a non-login interactive shell is started and is used to configure the shell.
    ~/.bashrc: executed by bash(1) for non-login shells.

    For example, the file could contain

    chromium-browser --kiosk www.google.com
    

    to launch Chromium in full-screen pointed to www.google.com


    Method 2:

    This solution works really well. Once the browser loads there is a small black square in the top left of the screen which seems to be a general bug (its mentioned on forums by others) but otherwise the fullscreen mode hides everything except the browser page.

    Edit the autostart file:

    sudo nano /etc/xdg/lxsession/LXDE/autostart 
    

    Comment out everything using a '#' at the start of each line and then add the following lines

    Auto run the browser

    @xset s off
    @xset -dpms
    @xset s noblank
    @midori -e Fullscreen -a http://google.com
    

    If necessary use the configuration tool to enable auto running of the GUI on powerup

    sudo raspi-config
    

    If you need to exit back to the command prompt CTRL + ALT + F1

    CTRL + ALT + F2

  • make a .sh file with the commands 'python /path/to/your/script.py' type 'sudo nano /etc/rc.local' and type the path to the .sh file

    before

    exit 0
    

    Or you could just type in

    crontab -e
    

    or

    sudo crontab -e 
    

    if you want the script to run at startup

    inside the file type in

    @reboot python /path/to/your/script.py &
    

    The use of **full paths** is strongly encouraged for crontab entries!

  • You could place your script at the bottom of /etc/profile file.

    Other options did not work for me, but this is maybe because I placed my script on the desktop.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM