Running a script during booting/startup; init.d vs cron @reboot

init.d, also known as SysV script, is meant to start and stop services during system initialization and shutdown. (/etc/init.d/ scripts are also run on systemd enabled systems for compatibility).

  • The script is executed during the boot and shutdown (by default).
  • The script should be an init.d script, not just a script . It should support start and stop and more (see Debian policy)
  • The script can be executed during the system boot (you can define when).

crontab (and therefore @reboot).

  • cron will execute any regular command or script, nothing special here.
  • any user can add a @reboot script (not just root)
  • on a Debian system with systemd: cron's @reboot is executed during multi-user.target.
  • on a Debian system with SysV (not systemd), crontab(5) mention: Please note that startup, as far as @reboot is concerned, is the time when the cron(8) daemon startup. In particular, it may be before some system daemons, or other facilities, were startup. This is due to the boot order sequence of the machine.
  • it's easy to schedule the same script at boot and periodically.

/etc/rc.local is often considered to be ugly or deprecated (at least by redhat), still it had some nice features:

  • rc.local will execute any regular command or script, nothing special here.
  • on a Debian system with SysV (not systemd): rc.local was (almost) the last service to start.
  • but on a Debian system with systemd: rc.local is executed after network.target by default (not network-online.target !)

Regarding systemd's network.target and network-online.target, read Running Services After the Network is up.


Firstly, a clarification is in order:

  • init.d is the directory that stores services control scripts, which control the starting and stopping of services such as httpd or cron
  • rc.local is a service that allows running of arbitrary scripts as part of the system startup process

In terms of whether its better to use rc.local or cron to run your script, I suspect that it is more a question of aesthetics more than practicality. cron, as a task scheduler, is intended as a method to perform maintenance or upkeep to a machine, such as checking updates, cleaning caches, or performing security audits. This doesn't mean that it is limited to performing those functions, as it can run any script or command desired at the specified time (such as @reboot).

Using rc.local, on the other hand, would fall more within a system configuration type of task, as rc.local, being executed by the machines init system, is typically responsible for setting the machines network configuration, services or environments (but again, is not limited to just this task).

Both of these points, however, should be tempered by the fact that not all init systems offer an rc.local mechanism, and not all cron daemons offer an @reboot psuedo tag.

Bonus Points

As mentioned, init.d is the directory that contains the scripts that control services that can be started or stopped on your system (at least on machines that use a SysV type init system). Depending on your init system and the purpose of your script, it may be reasonable to convert your script into an init script to be run in the same manner as a service. This, however, is heavily dependent on your init system as the framework surrounding how these files are constructed can differ greatly.

Last Word

It should also be noted that typically bash scripts end with a suffix of .sh rather than .txt, as this immediately denotes the file is a shell script instead of a text file. That being said, provided it either has a shebang (#!/bin/bash) at the top of the file, or is called as bash /path/to/script.whatever, it shouldn't matter in terms of executing the script.


I am writing my answer below ;

Q1: What is the key differences between the two?

Apart from the differences mentioned by other users above, I would like to highlight the point that @reboot is dependent on crond daemon. You are dependent on the order in which crond starts. Although most of the cases, crond starts fine but it may fail sometime to start (atleast I have seen some failures in some of my projects). When you write an init script, failure would typically occur if you do something wrong in your script (an ex: relying on a service that will start after your service)

Q2: Which is more robust?

Based on above, I think that init is more robust. But there is another point as mentioned by "Franklin Piat" in the first answer. Usually you need init script for a daemon and you should follow the policy

Q3: Is there a better one out of the two?

I do not think so (rc.local is little bit old and deprecated)

Q4: Is this the correct way of embedding a script to run during booting?

Yes. Usually application/package writers do in this way.