57

I am currently trying to understand the difference between init.d and cron @reboot for running a script at startup/booting of the system.

The use of @reboot (this method was mentioned in this forum by hs.chandra) is some what simpler, by simply going into crontab -e and creating a @reboot /some_directory/to_your/script/your_script.txt and then your_script.txt shall be executed every time the system is rebooted. An in depth explanation of @reboot is here

Alternatively by embedding /etc/init.d/your_script.txt into the second line of your script ie:

#!/bin/bash
# /etc/init.d/your_script.txt

You can run chmod +x /etc/init.d/your_script.txt and that should also result for your_script.txt to run every time the system is booted.

  1. What are the key differences between the two?
  2. Which is more robust?
  3. Is there a better one out of the two?
  4. Is this the correct way of embedding a script to run during booting?

I will be incorporating a bash .sh file to run during startup.

muru
  • 72,889
3kstc
  • 4,706

3 Answers3

44

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.

  • In my Ununtu 16.04, I need to remove /var/run/crond.reboot file each time, if I want than @reboot cron jobs are executed every time the sistem starts up. If this file existis @reboot cron jobs won't be executed – Albert Català May 20 '16 at 10:56
  • @Albert-Catala submit a bug to Ubuntu! – Franklin Piat May 20 '16 at 14:24
13

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.

wraeth
  • 458
  • bash scripts typically do not (and arguably should not) end with an sh extension. – mikeserv Mar 08 '15 at 03:08
  • 1
    @mikeserv: While I agree that most bash scripts do not (and arguably should not) have any extension, usually files with the ".sh" extension are bash scripts -- see "What's a .sh file?" . – David Cary Jun 18 '15 at 04:46
  • @DavidCary - that doesn't seem like a very authoritative source. – mikeserv Jun 18 '15 at 04:54
  • 1
    Wikipedia: "list of filename extensions" and Wikipedia: "shell script" also mention the surprisingly common ".sh" extension, with references. – David Cary Jun 21 '15 at 02:41
  • 1
    "typically bash scripts end with a suffix of .sh rather than .txt" - specifically meaning sh is more accurate as a file name extension for bash scripts (or other shell scripts) than txt which typically denotes plain-text. You can use whatever extension makes you giggle, but common convention would be, if using an extension sh would be more appropriate and is commonly used; though it isn't required, especially for scripts that are intended to be executed from the PATH. – wraeth Jun 22 '15 at 05:19
3

I am writing my answer below ;

  1. 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)

  1. 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

  1. Is there a better one out of the two?

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

  1. Is this the correct way of embedding a script to run during booting?

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

muru
  • 72,889
shubham
  • 417