Creating a portable, informative startup-script manager

Albert Liang
Tech Sketches
Published in
3 min readDec 21, 2016

TL;DR: How I manage startup scripts in bash

There are already a number of ways to implement start-up scripts in Ubuntu/bash:

  • Linking your script in rc.local
  • Linking your script in crontab
  • Making your script compatible with System V/Upstart/systemd

All of these methods are built-in and natively available in most Linux-based operating systems, and while I would normally prefer an out-of-the-box solution over a third-party solution, they all have their quirks:

  • rc.local scripts run as root, so you have to remember to explicitly change the user each time
  • rc.local sometimes runs “too early” in the start-up sequence (depending on the resources you need available for your script, such as a network mounted drive)
  • crontab doesn’t work reliably (at least in my experience, @reboot has never worked)
  • crontab (and perhaps rc.local as well) requires absolute paths to your script (and your script itself must also use absolute paths, too, to be extra sure)
  • to be very honest, I’ve been too lazy to learn System V/Upstart/systemd, but the problem here is that start-up daemons are continuously being deprecated and replaced

NB: The above-mentioned start-up methods do work — Stack Overflow has a myriad of solutions and patches to make your script work.

So what’s a sys-admin to do given the myriad of pitfalls and problems? Over-engineer a solution! (Note: I’m still relying on rc.local for this solution, but attempt to propose a more user-friendly approach.)

What you’ll need:

  • bash (I don’t think this method relies on bash-isms, but I also didn’t test it on other shells)
  • tmux (download it from apt-get, aptitude, et cetera…)

The first thing you’ll need to do is develop your start-up script. Assuming you have that, next you create the tmux wrapper script that will manage the starting of these scripts:

startup_manager.sh:

#!/bin/bashBASEDIR='/home/user'  # use absolute paths, just in casetmux new        -s startup    -d  "script1.sh"
tmux new-window -t startup:1 "script2.sh"

Some quick explanation:

tmux new -s creates a new tmux session named “startup”

tmux new -s -d means the tmux session is “detached” (i.e., runs in the background)

tmux new-window -t creates a new window (or tab, if you prefer to call it that) in the existing terminal named “startup” (the :1 creates the new tab in the “1” position)

If you have more startup scripts, you can continue to add lines like:

tmux new-window -t startup:2      "script3.sh"
tmux new-window -t startup:3 "script4.sh"

That’s it for the “programming” part! Now all you have to do is add your startup script to your /etc/rc.local (if you’re not using Ubuntu, this path might be different)

/etc/rc.local:

#!/bin/sh -esu user -c '/home/user/startup_manager.sh'
exit 0

Explanations:

su user changes the user from “root” to “user” (change user to match the username you use)

su user -c executes the command following the -c (and in this case, I gave the absolute path to my script, just to be sure it’s executing the right script)

You’re done!

What the heck, you’re still using rc.local! How is this any better?

  • su user is only declared once, so you’ll never need to remember to do that anymore (unless you want to run as root, or maybe you want to launch startup scripts from multiple user, but that wasn’t my use case)
  • the tmux window that each script runs in can output logging information to stdout, instead of redirecting it to a log file, giving you easy debug information (although good practice is to still write to a log file for archiving)
  • the scripts in each tmux window run independent of each other, so you can use while or sleep commands to force a particular startup script to wait for a resource to become available (such as a network drive) without blocking other startup scripts
  • you can use relative paths in your startup scripts

I hope this was useful! Leave a comment if you have questions, or have suggestions to make it better.

Disclosure: I’ve only been “programming” in bash for 7 years and do not claim to be a Linux or bash guru. This method probably has corner cases and race conditions — but that completely depends on the type of scripts you are trying to run at startup.

--

--

Albert Liang
Tech Sketches

Tech junkie, entrepreneur dreamer, practical engineer