I've got a script that gets run during boot on a Debian server. It's getting run too early, but I can't control when it's fired off. I can force the script to delay its own run with:

sleep 60

...or, alternately, I could just try the action a few times, like this:

while [ $ACTIONWORKED -eq 0 ] && [ $TESTRUN -le 5 ]; do
      # run the action i want
      # quick test if it worked
      # if yes, set ACTIONWORKED=1
      # if no, sleep 10
      # increment TESTRUN

What's a better way to test that the system is ready? The script will be run at other times during system operation, so the test is needed to differentiate between "booting-can't-do-this-yet" and "not-booting-run-now" states. I don't want it to wait every time the script runs.

Edit: Thanks for the ideas so far. Keep 'em coming if you have alternatives to what's already been posted.

To those who've asked for specifics, I've left them out of the question specifically to gather answers that work with the general Linux boot process.

Assume a "fully booted" system has presented a login prompt (via console, X, or whatever).


Really the best way to do what you want is to insert a call to the script in the proper place in SysV init. I'd recommend that you write a script that calls your script, and cajole your sysadmin until he or she installs it in the proper place.

EDIT: Okay, I just read your other question, and I see that you are talking about a script that is fired asynchronously, when someone plugs in a device. What you want to do is check the runlevel to see if it's 2 (or whatever your default runlevel is if you've changed it, and also 1 if you want this to run in single-user mode.) If I'm reading the Debian FAQ correctly, the runlevel does not change to the default until the boot is complete.

|improve this answer|||||
  • can't do it. i am the sysadmin. i need a good test. – quack quixote Nov 5 '09 at 21:10
  • ah, now that's useful. another answer suggested checking the runlevel but i didn't know when that would change. – quack quixote Nov 5 '09 at 21:27
  • 2
    My understanding is that all the /etc/rcS.d scripts are run first, and then it switches to runlevel 2 (or whatever is the default) and runs all the scripts in /etc/rc2.d – Brent Nov 5 '09 at 22:41
  • @brent: that's my understanding as well. my script is running during the early /etc/rcS.d scripts (S03, i think). so checking against the runlevel is probably the right test. – quack quixote Nov 5 '09 at 23:02

I would watch the init levels.

This should get you started..

 [[ `/sbin/runlevel | cut -d " " -f 2` == 5 ]] && echo "Ready"


|improve this answer|||||
  • 2
    it's debian, so testing against runlevel 2 would be more approproate. hmm. it wouldn't work if i ever needed single mode, but i'm not sure that's a concern. – quack quixote Nov 5 '09 at 21:29

On a debian system, you can specify the order something is run during boot by the number at the start of the script in /etc/rc?.d. So that the first script to be run at that runlevel would be /etc/rc?.d/S01scriptname - and the last would be /etc/rc?.d/S99scriptname. By ensuring your script is the only one that is prefixed with S99, it will ensure it is run last.

Alternatively, one of the last things to be done is to call /etc/rc.local. By calling your script from there, you could ensure it is called at the end of the boot process.

Another option would be to test for the file /etc/nologin - which is created at the start of boot, and removed at the end.

That being said - I don't think your idea of testing whether or not the script worked is a bad one. It ensures that nothing else gets in the way of the script running correctly.

|improve this answer|||||
  • the script is being run (forked, not exec'd) by an earlier script in the init chain, and i don't want to change that one. – quack quixote Nov 5 '09 at 21:15
  • actually on Debian lenny it'll be /var/lib/initscripts/nologin, and you need to set DELAYLOGIN=yes in /etc/defaults/rcS ... some versions may create /etc/nologin as a symlink to the one under /var but i haven't seen where yet. – quack quixote Nov 5 '09 at 21:52
  • and it's done in /etc/init.d/bootscripts.sh, which runs too late for this purpose. :( – quack quixote Nov 5 '09 at 22:07

You could add a script under rc3.d. Call it S99local and it will run after all the other scripts.

Scripts are executed in order S01xx to S99xx.

|improve this answer|||||
  • can't do it. the script is called from elsewhere. i could write another script (eg S99local) to call it again, but this is not an optimal solution. – quack quixote Nov 5 '09 at 21:12

You could also run it as a cronjob using @reboot as the time.

|improve this answer|||||

You're assuming that you need to see if the system is "ready", but what does that mean? What functionality to you require in order for this script to be running? Does the network need to be up and running? Does X11 have to have a logged in user? Check for those conditions directly, or find a better place to install the script that will execute when those particular steps are complete (i.e. postup stanza in /etc/network/interfaces or similiar).

|improve this answer|||||

Two pieces of information would greatly assist in finding an answer:

  1. Why can't you adjust when the script is fired off?
  2. What specific services/capabilities have to be ready/working for your task to succeed? X? networking? low system load? File shared mounted? Each of those things could be checked for; "system is booted" is too general and could encompass any or all of those.
|improve this answer|||||

The last file that is called in the boot process is a file called /etc/rc.local. Anything that you will place into that file will be run at the end of the boot process.

One example for a manual for this is http://www.netbsd.org/docs/guide/en/chap-rc.html

|improve this answer|||||

Here's a (truly ugly) solution:

  1. use this test in the script:

    while [ ! -e "/etc/yes-we-up" ]; do
        sleep 10
  2. add this to the end of /etc/rc.local:

    touch /etc/yes-we-up && chmod 644 /etc/yes-we-up
  3. create /etc/init.d/is-we-up,
    symlink it to /etc/rc0.d/K02is-we-up and /etc/rc6.d/K02is-we-up,
    and put this in it:

    #!/bin/sh -e
    # no we ain't
    rm /etc/yes-we-up
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.