How to Enable /etc/rc.local with Systemd

If you are running a Linux distro that uses Systemd, then you may find that your command in /etc/rc.local file would not run at system boot time. This guide explains how to enable /etc/rc.local script to run on system startup.

Enable /etc/rc.local on Systemd

If you type the following command in terminal:

sudo systemctl status rc-local

You may get this output:

 rc-local.service - /etc/rc.local Compatibility
 Loaded: loaded (/lib/systemd/system/rc-local.service; static; vendor preset: enabled)
 Active: failed (Result: exit-code) since Thu 2015-11-26 23:54:58 CST; 59s ago
 Process: 1001 ExecStart=/etc/rc.local start (code=exited, status=1/FAILURE)
Nov 26 23:54:57 vivid rc.local[1001]: File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 920, in require
Nov 26 23:54:57 vivid rc.local[1001]: needed = self.resolve(parse_requirements(requirements))
Nov 26 23:54:57 vivid rc.local[1001]: File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 807, in resolve
Nov 26 23:54:57 vivid rc.local[1001]: raise DistributionNotFound(req)
Nov 26 23:54:57 vivid rc.local[1001]: pkg_resources.DistributionNotFound: shadowsocks==2.8.2
Nov 26 23:54:58 vivid sudo[1008]: pam_unix(sudo:session): session closed for user root
Nov 26 23:54:58 vivid systemd[1]: rc-local.service: control process exited, code=exited status=1
Nov 26 23:54:58 vivid systemd[1]: Failed to start /etc/rc.local Compatibility.
Nov 26 23:54:58 vivid systemd[1]: Unit rc-local.service entered failed state.
Nov 26 23:54:58 vivid systemd[1]: rc-local.service failed.

And if you try to enable /etc/rc.local to run on system boot with the command:

sudo systemctl enable rc-local

You may get:

The unit files have no [Install] section. They are not meant to be enabled
 using systemctl.
 Possible reasons for having this kind of units are:
 1) A unit may be statically enabled by being symlinked from another unit's
 .wants/ or .requires/ directory.
 2) A unit's purpose may be to act as a helper for some other unit which has
 a requirement dependency on it.
 3) A unit may be started when needed via activation (socket, path, timer,
 D-Bus, udev, scripted systemctl call, ...).

The solution

As you can see from above, The unit file have no [Install] section. As such Systemd can not enable it. First we need to create a file:

sudo nano /etc/systemd/system/rc-local.service

Then add the following content to it.

[Unit]
 Description=/etc/rc.local Compatibility
 ConditionPathExists=/etc/rc.local

[Service]
 Type=forking
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
 RemainAfterExit=yes
 SysVStartPriority=99

[Install]
 WantedBy=multi-user.target

Save and close the file. To save a file in Nano text editor, press Ctrl+O, then press Enter to confirm. To exit the file, Press Ctrl+X.  Next, run the following command to make sure /etc/rc.local file is executable.

sudo chmod +x /etc/rc.local

Note: Starting with 16.10, Ubuntu doesn’t ship with /etc/rc.local file anymore. You can create the file by executing this command.

printf '%s\n' '#!/bin/bash' 'exit 0' | sudo tee -a /etc/rc.local

Then add execute permission to /etc/rc.local file.

sudo chmod +x /etc/rc.local

After that, enable the service on system boot:

sudo systemctl enable rc-local

Output:

Created symlink from /etc/systemd/system/multi-user.target.wants/rc-local.service to /etc/systemd/system/rc-local.service.

Now start the service and check its status:

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service

Output:

● rc-local.service - /etc/rc.local Compatibility
 Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled)
 Active: active (running) since Fri 2015-11-27 00:32:56 CST; 14min ago
 Process: 879 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)
 Main PID: 880 (watch)
 CGroup: /system.slice/rc-local.service

Cron @reboot

If the above method does not work for you, or you just want some simple commands to be executed on system boot, then you can also use the @reboot feature in cron to automatically execute command on system boot. For example, I want my shadowsocks client to auto start, so I open the root user’s cron file:

sudo crontab -e

And put the following line at the end of it.

@reboot /usr/bin/sslocal -c /etc/shadowsocks.json -d start

Save and close the file.

In some Linux distributions such as archlinux, the cron daemon is not enabled by default. So you have to manually enable it. To enable it on archlinux, enter the following command in the terminal.

sudo systemctl enable cronie

Shadowsocks is a socks5 proxy that can be used to bypass Internet firewalls, If you are interested, click the link below to learn how to setup your own shadowsocks server.

How to Use Systemd

Want to learn more about systemd to efficiently manage your system? Please read the following tutorial.

Rate this tutorial
[Total: 54 Average: 4]

29 Responses to “How to Enable /etc/rc.local with Systemd

  • Ricardo J. Barberis
    8 years ago

    On CentOS 7 you only have to do:
    # chmod +x /etc/rc.local

    Nothing more, nothing less.

    • Xiao Guo-An (Admin)
      8 years ago

      Thanks for the info!

    • Same with Ubuntu 20.04.

      Ref: /lib/systemd/system/rc-local.service

      # This unit gets pulled automatically into multi-user.target by
      # systemd-rc-local-generator if /etc/rc.local is executable.

  • longka
    3 days ago

    thank you so much

  • александр
    3 days ago

    Thank you so much!

  • Olav Alberts
    3 days ago

    Don’t forget the hashpling or `#!/bin/bash` in your rc.local !!
    Missing this will cause an exec / format error.

  • Liz Thompson
    3 months ago

    is this permanent?

    I need something permanent that executes every time the system is started
    $ xinput map-to-output 9 eDP1
    to fix the touch screen from overlapping the external monitor

    and here I thought Linux was a modern OS

  • Néstor Acevedo
    5 months ago

    rc-local.service – /etc/rc.local Compatibility
    Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled)
    Drop-In: /lib/systemd/system/rc-local.service.d
    └─debian.conf
    Active: active (exited) since Mon XXXXXXXXX UTC; 42s ago
    Docs: man:systemd-rc-local-generator(8)
    Process: 1881 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)

    • Xiao Guo-An (Admin)
      5 months ago

      Hi, please check /etc/rc.local exists and you have added execute permission to it.

      sudo chmod +x /etc/rc.local
      • Néstor Acevedo
        5 months ago

        Already exists and has execute permissions. I forgot to say, it’s Ubuntu 18.04 but I think it doesn’t matter.

        • Peter
          5 years ago

          I can run /etc/rc.local from the CLI, and my command runs when I do that, but when I live test it with a reboot, the command does not run. (in my case, I am sending a notify command to my Asterisk server)
          That tells me the rc.local file is executable, and permissions are all ok. But for some reason I can’t get it to run when it is supposed to.
          Making this tricky is that when I reboot, I lose my SSH connection so no way of logging what happens.
          Any suggestions?

  • I also tried it this way. The rebootphones2 file also works if entered manually in the CLI. But when I reboot, it does not occur. Any obvious problems with the syntax? (I also tried this with the command entered directly in the crontab line, but that also did not work)

    [root@freepbx ~]# crontab -l
    0 6 * * * /root/reloadasterisk.cron
    @reboot sleep 60 /rebootphones2

  • Very good article, but I think you need to add a line under [Unit]:

    After=network.target

    Because we usually expect rc.local to execute more or less at the end of the boot process.

  • Francisco Pezo Leon
    5 years ago

    He realizado con la información que dice no ejecuta

  • Contrab doesn’t work well for vnc4server. (Bad characters in lxterminal &)
    The only solution in Ubuntu 18.04 was “sudo systemctl start rc-local.service”
    Thank you! Thank you! You are the best 🙂

  • “sudo systemctl enable cronie”
    maybe “sudo systemctl enable cron” ?

  • пидр
    5 years ago

    соси сука

  • Paer Toernell
    5 years ago

    I get error:

    rc.local[2519]: /bin/sh: 0: Illegal option

    when i try to start the service

  • Thank you SO MUCH for this! This was a big help to me to wade through such a tortuous course to perform such a previously simple function! Things continue to be obfuscated further – sometimes it’s better to keep it simple!

  • Yavirac
    4 years ago

    Much needed, and still current. Great job.

    Thanks @linuxbabe

    @yavirac

  • Great solution with systemd (Ubuntu 18.04)!
    The only thing I have to modify is

    [Service]
    Type=forking
    ExecStart=/bin/sh /etc/rc.local

    my rc.local is like

    #!/bin/sh -e
    sudo -u …..

    thank you!

  • Richard
    4 years ago

    Good job in the explanation.

    As always, systemd has good news (well-defined user space control) and bad news (unnecessary complexity in some cases)

  • Peter Wein
    4 years ago

    Thanks! Super explanation! I had to follow right till the end (not crontab) on Ubuntu 20.04 but now it works!

  • Valentin
    3 years ago

    It works, thank you

  • kicksomedust
    3 years ago

    It indeed works for ubuntu 18.04

    thank you linux babe

  • Cutezen
    2 years ago

    This is the systemd way to do it. TPTB have been making rc.local more and more difficult to do and will eventually refuse to allow it.

    I do NOT put this in the same filesystem as the OS. I use the /opt directory on another drive to store this and any compiled and installed source package. It keeps the core install clean except for minor config. I do that for /home as well as backup devices. I can trivially wipe and install the OS as needed. I run a script to install all the configurations and packages I need. Just keep track of changes and update the script as needed. Store it on /opt as well.

    https://www.redhat.com/sysadmin/replacing-rclocal-systemd

  • AhmedAbdulMonem
    2 years ago

    Thanks A lot Xiao Guo-An

    Just one Added Note, In CentOS 7 & Above You’ve to change the service type from forking To simple

    Reference Here : https://unix.stackexchange.com/questions/615619/systemd-service-fails-with-exit-code-2-start-request-repeated-too-quickly

  • ACMilton
    5 months ago

    Thx for the info.
    Good work!!

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here