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).
I would watch the init levels.
This should get you started..
HTH
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.
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.
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.
You could also run it as a cronjob using @reboot as the time.
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).
Two pieces of information would greatly assist in finding an 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
Here's a (truly ugly) solution:
use this test in the script:
add this to the end of
/etc/rc.local
: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: