init.d scripts written in Python
A question came up on StackOverflow asking about writing init.d
scripts in Python. One comment indicated that these scripts should be programmed in shell, not Python. Is writing init.d
scripts in Python:
- Bad. Bad. Bad. Never do this.
- Not a recommended practice.
- OK, with caveats.
- Legacy dogma.
- Totally fine.
It would be great to know any nightmare scenarios, or if this rule is written in some sysadmin's blood.
I'd say #2, but very close to #1 -- "Bad. Bad. Bad. Never do this." The standard, such as it is, for Linux init scripts is in the LSB, and while it never comes out and says "these are bourne shell scripts", several assumptions are made. One, that lines beginning with # are comments, happens to work out fine. More problematic is the requirement that the init script execute the commands from /lib/lsb/init-functions
"in the current environment (see shell special built-in command dot)".
But more importantly, if you're doing anything really complicated here, you're doing it wrong. The init scripts should be very simple and utilitarian. They should be scripts in the classic sense, not programs. It's better to suck it up and make a simple shell script that any sysadmin can easily grok in one quick look than to make something beautiful and engineered in Python.
Another consideration to keep in mind is systemd
, which may or may not be the Future Of All System Initialization On Linux. Under systemd, initialization is done by simple configuration files rather than scripts, the idea being that all startup fits into several standard design patterns and really you should just have to pick one. If you program uses something complicated for initialization, that should go outside of the init script itself.
I don't see a problem with it, if you know, for sure, that the Python interpreter will be available when the init.d script is being run. This, to me, indicates that you're looking at something being done relatively late in a multi-user (or "graphic console") run-level.
However... This means that a specific version of the Python interpreter MAY be vital for your boot sequence and this is one more thng you need to check at upgrades.
I guess this means I'm saying "3. OK, with caveats".
I agree with "3. OK, with caveats," but for different reasons. My experience on Solaris was that they had an OS copy of Perl for some of their internal programs. The shell script was nothing more than the shell to get the Perl to kick off. Did the startup script have to be written in sh? No, but it improved maintainability for the administrator. And the init script did nothing more complicated that stuff like daemon --start
or daemon --stop
. If you did this, then regular users could start your tool in unprivileged mode, if that makes sense in the context of your program. And they wouldn't need to have all sorts of complicated settings to finesse.
Modern Linux distributions, even those still using init.d
, have a large collection of pre-built functions meant to make it easy to manage daemons. Graphical boot processes routinely leverage those functions to keep the pretty logo up unless one of the startup scripts begins spewing errors. Your Python code (or any other language) may not play well with those schemes.
If you don't care about aesthetics or maintainability, your init script can be written however you want. I've seen lots of admins, who can't even cut and paste properly, completely ignore command line arguments and they just start the daemon. No shutdown, status, or restart. It was immature, but their code still ran.
I say between #1-2. The LSB directs you this way.. and from a Sys-Admin (non dev role) the job req's dictate sh/bash knowledge, NOT dev-level (or even light understanding) of python, PHP or perl. That's for the LAMP stack, not for the system init scripts.