Skip to main content

Abstracting the inits -- run "service action" commands with ease!

On GNU/Linux, from time to time, we tend to face the issue with mistakenly using wrong service action commands on various init systems. For example, on a system with upstart being the init, one can mistakenly run

systemctl restart sshd

whoops! this is not a major mistake by itself but could easily turn into one (damn you muscle memory!)

and not to mention someone could pull a nice little prank on you by using something simple like alias systemctl='echo "Cracked"' , for example.

These mistakes happen the most when you have to login to many GNU/Linux systems with a variety of inits on them, so one could easily mistake one for the other. Coming back to this a bit later. Before moving forward, the correct command for restarting sshd service on upstart would be:

service sshd restart

Note the swapping of service (sshd) and action (restart) compared to systemd (systemctl restart sshd).

And, where to start with the init wars! I guess, we all could write thousand pages about this. Right now, it seems, systemd is winning (!) the war as all major distros are adopting/adopted systemd as init. But many people including me dislikes systemd for being the do-it-all ecosystem instead of just solving the problem it was meant to solve i.e. being the PID 1. It essentially breaks the year old Unix philosophy:

Do one thing, and do it (very) well.

That's why we have so many (cheap) IPCs on *nix BTW.

Enough... let's put this debate/discussion for another post. Moving on...

Now, wouldn't it be better if we had something that would abstract away all the init specific headaches and we just needed to mention the service and action name to perform an action? Moreover, that would make our job much easier when we need to simultaneously login to multiple servers with varying inits!

Is there anything available?

Ummm... I wasn't sure. So, I created my own!

This is the power of GNU/Linux; you can always craft your own stuffs to meet your need. Thank you Mr. Stallman and Mr. Torvalds.

The name of the program is wrapserv -- I've written it in Python (Thank you Mr. van Rossum).

Directly quoting wrapserv's README:

wrapserv is a script for running "service action" commands (e.g. docker restart) with all the init specific commands/arguments abstracted away. Works with systemd, upstart, sysv inits.

You just need to put the service name and desired action. Examples:

wrapserv docker restart
wrapserv nginx reload

Multiple "service action" pairs are supported too e.g.

wrapserv docker stop nginx status postfix start

here, wrapserv will first stop docker (dokcer stop); if succeeds, will check the status of nginx (nginx status), and if that succeeds, will start postfix (postfix start), in that order. So, this is essentially same as running

wrapserv docker stop && wrapserv nginx status && wrapserv postfix start

In systemd, you can specify the unit types too e.g.

wrapserv nginx.service reload
wrapserv status

If you just want to know the name of the init you have:

wrapserv -i
wrapserv --show-init-name

The project is on GitHub and GitLab; here is the direct like to the wrapserv main script:

How to install:

  1. Get the script: Either 1) clone the repository (recommended): git clone Or 2) download the script (in raw): wget
  2. Make the script executable (if you're downloading only the script directly): chmox +x wrapserv
  3. Put the script in any place in your PATH; best to have your ~/bin/ in PATH and put it there, or you can put it any standard directory e.g. /usr/local/bin/ (if available) or /usr/bin/. Here, i'm putting the script in /usr/bin/: sudo mv wrapserv /usr/bin/
  4. Creating a symlink would do too: sudo ln -s "$PWD"/wrapserv /usr/bin/

Note: The advantage of using ln over direct cp/mv is that when you pull (git pull ... or wget/curl download) new changes from upstream, you don't need to cp/mv these every time. Another option would be to put the directory itself in the PATH, but this is not recommend.


Comments powered by Disqus