Archives

Tags

Showing articles written in October 2009. Show all articles

Running Linux processes as Daemons

Running an arbitrary process, such as a Python script, on your Linux box as a daemon is really quite simple if you have the right tools.

In my case, I had a simple Python socket server that needed to run permanently. Simply running it in the background (Ctrl-z) is no good as it would die the moment I logged off!

Enter daemon, a really handy tool for solving this exact problem.

Installation is easy. On Debian-based distros, you can just install it directly form aptitude. On CentOS, which uses yum, I had to install it from source. But I ran into no problems there.

Once installed, getting things running was easy:

$ daemon -r --name=myserver python /full/path/to/myserver.py

The "r" flag tells daemon to respawn itself if the service is killed. I've given it a name so I can refer to it later. And the rest of the line is the actual command I want to run.

To test if the process is still running, you can look in ps or pgrep, but the best way to do it is to simply ask daemon personally:

$ daemon -v --name=myserver --running

The "v" flag is for verbosity (of coarse). The "running" flag tell daemon that I want to know if the process specified by "name" is still running. The output you receive is simple to interpret, e.g: "myserver is running with PID: 23324".

To finally kill the process at some point in the future, you can issue the following command:

$ daemon -v --name=myserver --stop

And this one should be rather self-explanatory by now. :)

I've only grazed the surface here. Just check out the man page for an idea of how much more you can do with this. Good luck, muchachos!

Let me do it, Python!

Python is great. It's nearly at the top of my list of "most usable" programming languages.

But one thing annoys me. It's even been explained in detail, and it still annoys me!

Basically, the join() method is defined on the string class and not on the list/tuple class. Now, I admit, it's not really that big of a deal. It's hardly going to make me drop Python into the abyss of "tried, but shitty" languages.

When I was first learning Python, I knew that joining a list/array of strings on a specific delimiter would be part of the standard library. Here is what I tried:

["Balls", "to", "the", "walls"].join(", ")

But, no! Python makes me do this:

", ".join(["Balls", "to", "the", "walls"])

Eww! It's both backwards and ugly! Let me do it by way, Python! In Ruby, I could just duckpunch the hell out of the class and implement my own method. But thats another story...

The thing that bothers me the most is that you actually have to pass a list into the method. If the join method must be on string, then I should atleast be able to pass in an arbitrary number of arguments, like so:

", ".join("Balls", "to", "the", "walls")

I mean, Python does support optional arguments, after all. And if I have a list I want to join, I could just apply the list as arguments:

# Doesn't work...
args = ["Balls", "to", "the", "walls"]
", ".join(*args)

One other thing that (slightly) bothers me is that it also forces me to pass in a list of string objects. Being dynamically-typed and very-high-level, I would have expected Python to forcfully stringify any non-string members of the supplied list.

", ".join(["Balls", 2, "the", "Walls"])    => ERROR!

C'mon, Python. You already give me the option of writing questionable code by allowing me to access private instance methods externally (Note: I've never done this).