Make runs commands to create and/or transform files and uses the files' timestamps to determine if a command needs to be executed or can be skipped. For example:
foo: $(info Creating foo ...) touch foo
When you save the above in a file called
Makefile and run
make foo it will output
"Creating foo ..." and create an empty file
foo. When you call
make foo again make detects that
foo already exists and simply prints
"'foo' is up to date" without calling
We can use this behavior to start a server and store its process ID (PID) in a file:
server.pid: http-server . & echo $$! > $@
Let's break this down.
http-server is a simple web server that can be installed via npm (
npm install -g http-server). But you can use any other server implementation you like. The "
&" sends the server process into the background (i.e. it doesn't lock the console). "
echo $$! > $@" writes the PID (
$$!) to the file
make server.pid will start the server and create
server.pid just like the touch example above. It will also not start the server again if
server.pid is already present.
We can now create a make target that allows us to start our server with the command
This simply means "The target '
start-server' depends on the file
server.pid. So make sure it exists to complete this target."
Stopping the server is a bit more envolved:
stop-server: test -f server.pid && kill `cat server.pid` && rm server.pid || true
test -f" tests if
server.pid is present and stops if it's not. "
kill" ends the process with the ID that's stored in
server.pid and "
rm" deletes the file. The last bit "
|| true" ensures that make returns without an error if
server.pid does not exist.
The entire Makefile looks like this:
start-server: server.pid stop-server: test -f server.pid && kill `cat server.pid` && rm server.pid || true server.pid: http-server . & echo $$! > $@
.PHONY bit tells make that
stop-server are targets that (unlike
server.pid) do not correspond to files with those names.
Now you can start and stop your server like so:
$ make start-server $ make stop-server
There is one caveat with this approach. In case you forget to
make stop-server before shutting down your machine you end up with a stale
server.pid file that you have to delete manually before you can start the server again.
Happy serving! ;-)