Trying to use after.local and $RUNLEVEL

Hi All

I need to run a command at the end of runlevel 3 and I think I have done my reading. “after.local” seems to be the answer but I am having touble getting the runlevel detected correctly. I finally executed the following:

echo "$RUNLEVEL" >> /var/tmp/test_file


if  "$RUNLEVEL" = "3" ]
then
   echo "I Ran in " >> /var/tmp/run_level_3
fi



The file test_file is created but it contains blank lines. run_level_3 is never created.

So, the fact that test_file exists indicates that after.local is being run but I must be messing up how to test the runlevel. Does anyone see an obvious issue with my little test?

Thanks

Where did you read that a variable RUNLEVEL does exist in the environment where the script runs?

In any case it does exist when I simply run bash from a loged in session:

henk@boven:~> echo $RUNLEVEL

henk@boven:~>

And of course when it isn’ there, it does not have the value 3 (or any other value) and thus your “if” will be “false” and the second “echo” will not execute.

On 2015-09-15 21:36, hcvv wrote:
>
> Where did you read that a variable RUNLEVEL does exist in the
> environment where the script runs?

I think old initd used it.

However, if you (iKevin) need to run something at a certain level, it is
better to use a systemd service installed at that “target”, or an initd
script, using the compatibility layer.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

[QUOTE=robin_listas;2728315

However, if you (iKevin) need to run something at a certain level, it is
better to use a systemd service installed at that “target”, or an initd
script, using the compatibility layer.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))[/QUOTE]
I agree with that. It is always wise to use the present standard when creating something new and not to use some compatibility with the old.

Thanks for the fast responses. @hcvv The RUNLEVEL environment variable came from the header information in /etc/init.d/after.local. There are a few examples that use it in the forum. I must have not fully understood.

@robin_listas. I will look into systemd.

Thanks all,
iKevin

On 2015-09-16 00:46, iKevin wrote:
>
> Thanks for the fast responses. @hcvv The RUNLEVEL environment variable
> came from the header information in /etc/init.d/after.local. There are
> a few examples that use it in the forum. I must have not fully
> understood.

No, you are right, the variables are documented there.

You have to add this section near the top:


if test -s /etc/rc.status
then . /etc/rc.status
else exit 1
fi

Then you will have access to those variables.

If it works, you have detected a bug, and you can make the official
report (at bugzilla) with a proposed solution already :wink:


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

Thanks for the explanation. I assume that with this story you mean this fact:

henk@boven:~> cat /etc/init.d/after.local
#! /bin/sh
#
# Copyright (c) 2010 SuSE LINUX Products GmbH, Germany.  All rights reserved.
#
# Author: Werner Fink, 2010
#
# /etc/init.d/after.local
#
# script with local commands to be executed from init after all scripts
# of a runlevel have been executed.
#
# Here you should add things, that should happen directly after
# runlevel has been reached.  Common environment
# variables for this are:
#  RUNLEVEL  -- The current system runlevel.
#  PREVLEVEL -- The previous runlevel (useful after a runlevel switch).
#

henk@boven:~>

Thus , when RUNLEVEL is not defined (or defined but empty), that basicaly is a bug.
I am afraid that such things will happen more and more. Because, while basicaly systemd is made to interface with sysvinit, that will become more difficult when systemd develops over time. And the urge to test every new systemd change against sysvinit will diminish.

Thus better create a systemd thingy.

On 2015-09-16 10:16, hcvv wrote:

> Thus , when RUNLEVEL is not defined (or defined but empty), that
> basicaly is a bug.

No.

That variable is defined in “/etc/rc.status”, which all init scripts
must import. If you have a look at existing scripts in /etc/init.d/, you
will see that most do, in a way similar to the code I posted in my
previous post.

The bug is that someone forgot to include those lines in the sample
/etc/init.d/after.local, while at the same time documenting the variables.

In fact, it is that “/etc/rc.status” which does the systemd take over of
old init.d scripts:


# Check if the service is used under systemd but not started with
if test -z "$SYSTEMD_NO_WRAP" && /usr/bin/mountpoint -q
/sys/fs/cgroup/systemd; then
if test $PPID -ne 1 -a $# -eq 1 ; then
_rc_base=


So “/etc/rc.status” will be supported for the foreseeable future :slight_smile:


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

Thanks for all the help. I finally got things working with systemd. I did run into one tricky issue. I used some simple examples to run a script at startup. Most of these show have an entry as follows:

[Service]
Type=Oneshot
....

The script that I am running is a license manager (lmgrd) and it would quickly die. I did some reading (I am unskilled with systemd) and it seemed that I should be using the option:

[Service]
RemainAfterExit=yes
.....

This, in fact, worked. So, just in case it helps somebody else, this is my *.service to start lmgrd.


[Unit]
Description=License manager
After=network.target


[Service]
RemainAfterExit=yes
User=my_uername
ExecStart=/usr/local/bin/startLm


[Install]
WantedBy=multi-user.target



startLm is my one line script that actually runs lmgrd.

Thanks All.

Thanks for reporting back with your solution. It might indeed help others as systemd is rather new here and we have all to learn it’s tricks.