It's a UNIX system

Running a background process as a specific user on Linux startup

Long, long ago when I was a student, I knew how to recognise a UNIX system. Sorry: overused in-joke. I’ve been brushing up on Linux (Ubuntu 14.04 on Azure) while doing some ops stuff involving a machine which, on startup, automatically runs a background process as a specific user. A few minutes of research revealed several ways to do this. Probably the technically rigorous option is a Linux service; I found a much easier option that works well for my purposes.

Our dev team has been building a service process (I’ll call it antelope) that must run in the background as user youjane. The user is important because the process may push changes to a cloud-hosted Git repo, and we want to distinguish automated commits from those made by a human. Also, antelope adheres to the 12 Factor App manifesto which, among other things, recommends configuration by environment variable; in our case there are two: FN, LN.

 

The manual way

This is easy enough to do by hand:

graham$ login youjane
graham$ password:
youjane$ export FN=wilde
youjane$ export LN=beest
youjane$ /opt/antelope/bin/antelope &

The trailing ampersand (&) tells Linux to run the process in the background. This works fine.

 

An automatic way

I don’t want to do this by hand every time one of our antelope machines starts up. To make the OS do it, I wrote a small script and edited system file /etc/rc.local to call the script. I’ve described my steps below.

Change to user root in order to modify system files:

$ sudo -i

 

The script file

Create a script file in a directory suitable for admin scripts:

# vi /usr/local/bin/run_antelope.sh

 

The sudo command lets you define environment variables in its argument list. I’ve included the full script below:

#!/bin/sh

# sudo arguments:
# "-b" run in the background
# "-E" preserve the user's environment
# "-u youjane" run as user "youjane"
# Set environment variables:
# FN=<value>
# LN=<value>
sudo -b -E -u youjane
  FN=wilde \
  LN=beest \
  /opt/antelope/bin/antelope

 

Save the file and close the editor. Adhering to the principle of least privilege, make it executable only for its owner (root):

# chmod u+x /usr/local/bin/run_antelope.sh

 

/etc/rc.local

To run shell script on start-up, edit the system file /etc/rc.local:

# vi /etc/rc.local

 

Add the line below (before the line with exit 0) to run the script:

/usr/local/bin/run_antelope.sh || exit 1

exit 0

 

If the script fails, || exit 1 is there to signal the failure to the init system.

Save the file and close the editor.

Now antelope will start automatically when Linux starts up.

 

Does it work?

So I could do some testing with antelope or check the log file. But wouldn’t it be cool just to look at the important bits of its process environment? It’s easy to do that with the /proc/<pid>/environ file.

To avoid corrupting my quick smoke test, I logged in as root (instead of youjane). In the interactive shell sequence below:

  • Command xargs formats the contents of /proc/<pid>/environ to make it readable.
  • Command $(pidof antelope) gets the ID of the running process.
  • The output shows that antelope is running as youjane, and environment variables FN, LN are available and defined as expected.
# xargs --null --max-args=1 < /proc/$(pidof antelope)/environ
UPSTART_INSTANCE=
runlevel=2
UPSTART_JOB=rc
TERM=linux
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
RUNLEVEL=2
PREVLEVEL=N
UPSTART_EVENTS=runlevel
PWD=/
previous=N
LOGNAME=youjane
USER=youjane
USERNAME=youjane
SUDO_COMMAND=/opt/antelope/bin/antelope
SUDO_USER=root
SUDO_UID=0
SUDO_GID=0
FN=wilde
LN=beest

 

As always, comments are welcome.

 

References

 

Leave a Comment

Scroll to Top