Put your script in /etc/network/if-up.d
and make it executable. It will be automatically run each time a network interface comes up.
To make it do work only the first time it is run on every boot, have it check for existence of a flag file which you create after the first time. Example:
#!/bin/sh
FLAGFILE=/var/run/work-was-already-done
case "$IFACE" in
lo)
# The loopback interface does not count.
# only run when some other interface comes up
exit 0
;;
*)
;;
esac
if [ -e $FLAGFILE ]; then
exit 0
else
touch $FLAGFILE
fi
: here, do the real work.
If you've done everything such as chmod +x /etc/rc.local
then your command is running, it's just not getting logged anywhere that you can see it.
Example
This is my /etc/rc.local
:
$ cat /etc/rc.local
#!/bin/bash
touch /var/lock/subsys/local
echo "hickory stick"
Here I've used the modified Bash which logs to syslog which I discussed in this other U&L Q&A titled: Sending bash history to syslog.
When my system boots I see the following message getting logged via Bash:
/var/log/bash-log/127.0.0.1.log:2018-07-24T22:04:24.609094-04:00 centos7 rc.local: hickory stick
But no where else. To get this to log to syslog/rsyslog you typically can use the logger
command to do so:
$ logger hi
You can then see it in your /var/log/messages
or /var/log/syslog
or journal -xef
. Here I'm using journald:
$ journalctl -xef
Jul 24 20:23:04 centos7 bash[1629]: HISTORY: PID=1629 UID=0 USER=root CMD=man logger
Jul 24 20:23:24 centos7 bash[1629]: HISTORY: PID=1629 UID=0 USER=root CMD=logger hi
Jul 24 20:23:24 centos7 vagrant[1811]: hi
You should be able to use logger
to capture output from commands in scripts like so:
$ cat /etc/rc.local
#!/bin/bash
touch /var/lock/subsys/local
echo "hickory stick" | logger
Now when we reboot:
$ journalctl -xef
...
Jul 24 20:31:41 centos7 bash[1629]: HISTORY: PID=1629 UID=0 USER=root CMD=journalctl -xe
Jul 24 22:24:00 centos7 logger[1286]: hickory stick
Jul 24 22:24:00 centos7 sshd[1270]: Server listening on 0.0.0.0 port 22.
Jul 24 22:24:00 centos7 sshd[1270]: Server listening on :: port 22.
Jul 24 22:24:00 centos7 systemd[1]: Starting Permit User Sessions...
We see our message there via logger
that we added to /etc/rc.local
.
Extra info
logger
is a pretty useful and you can have it log to a file instead of via the -f
switch, you can also control the tag that shows up in the logs with the -t
switch.
$ logger -t "smurfs" hi
$ journalctl -xe | grep smurfs
Jul 24 20:38:24 centos7 smurfs[1764]: hi
References
Best Answer
At the time that this answer was first written, Debian (as installed by default) used "SysV" rc scripts with the
start-stop-daemon
binary. There was an example script, in the file/etc/init.d/skeleton
, that one could as a base for one's rc script. Once one had one's rc script and it was marked as executable, theupdate-rc.d
command could be used to add it to desired run levels.As the years have gone by, things have changed. In 2014, in particular, two things changed:
/etc/init.d/skeleton
script was superseded by the example script in theinit-d-script
(5) manual page, which later in 2018 became the only available base when/etc/init.d/skeleton
was done away with completely. The content of the skeleton also changed significantly, no longer needing people to write calls tostart-stop-daemon
or indeed to write much more than some variable assignments. (See https://unix.stackexchange.com/a/480897/5132 .)systemctl enable
. There was no example unit file, though. (See https://github.com/systemd/systemd/issues/10572 .)So as of 2018 you need to write a systemd service unit file that (at the very least) names your script (using an absolute pathname) in an
ExecStart
setting. You might be wanting, although the question does not specify one way or another, to use aUser
setting to have the script run under the aegis of your user account and not the superuser's. And you might, again depending from things not specified in the question, need to coördinate the relative order of invoking your script and the (auto)mounting of your home directory if it is separately mounted.