4

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:

TESTRUN=0
ACTIONWORKED=0
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
done

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

9 Answers 9

1

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.

4
  • can't do it. i am the sysadmin. i need a good test. Nov 5, 2009 at 21:10
  • ah, now that's useful. another answer suggested checking the runlevel but i didn't know when that would change. Nov 5, 2009 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, 2009 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. Nov 5, 2009 at 23:02
5

I would watch the init levels.

This should get you started..

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

HTH

1
  • 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. Nov 5, 2009 at 21:29
2

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.

3
  • 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. Nov 5, 2009 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. Nov 5, 2009 at 21:52
  • and it's done in /etc/init.d/bootscripts.sh, which runs too late for this purpose. :( Nov 5, 2009 at 22:07
1

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.

1
  • 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. Nov 5, 2009 at 21:12
1

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

1

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

0
0

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

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

0

Here's a (truly ugly) solution:

  1. use this test in the script:

    while [ ! -e "/etc/yes-we-up" ]; do
        sleep 10
    done
    
  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
    

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .