Execute Shell Script on Boot

1 minute read

I have built a rootfs with buildroot, rootfs is squashfs with overlayfs support for ease of writting configuration files such as dropbear that needs write permission on /etc directory.

If an app needs to be started on boot, add a script with name like S+[num]+app to /etc/init.d/, and the script will be called during startup by /etc/init.d/rcS.

This works perfect until I need to execute a script for test purpose, and it is required to start on boot and run forever, based on the above knowledge, I wrote a script and copied to the /etc/init.d directory and do a reboot (in adb shell), to my surprise, I cannot reboot the system with reboot command (adb reboot works), another interest thing is after reboot command issued, the script start to running.

Why?

  • Does my script get called during startup?
  • Does it matter with the while loop I used?
  • Do I have to follow the start-stop-daemon rules?

I tried to build the script into file system, and it works, so it’s not the content I have in the script, it is just get ignored on boot. So I added set -x to /etc/init.d/rcS to see every commands executed during the boot process, and it confirmed my assumption, now I realized I forget something crucial, I am using overlayfs, and they were mounted in S21mountovl.sh, this is the cause of this problem, because rcS list the scripts under /etc/init.d before the /etc/ was mounted, so my script is not in that list, and not get called at all.

#!/bin/sh


# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do

     # Ignore dangling symlinks (if any).
     [ ! -f "$i" ] && continue

     case "$i" in
	*.sh)
	    # Source shell script for speed.
	    (
		trap - INT QUIT TSTP
		set start
		. $i
	    )
	    ;;
	*)
	    # No sh extension, so fork subprocess.
	    $i start
	    ;;
    esac
done

This explains why it’s get called when I do a reboot, on reboot, all the scripts are also get called by /etc/init.d/rcK, the difference is it call stop part of the script.

I tried to modify rcS long time ago, but cannot get it working, now, it has an explanation.