Makefile multiline dash command run executable in a detached process
I have the following target in my makefile: (I'd like to run python http server in a detached process and when bash script is done kill the server)
TEST_PORT = 17777
test::
$(ENV_VARS)
python -m SimpleHTTPServer $(TEST_PORT);
PID=$$(lsof -t -i @localhost:$(TEST_PORT) -sTCP:listen);
echo $(PID);
if [ -n "$$PID" ];
then
python test.py;
fi;
function finish {
if [ -n "$$PID" ];
then
kill -9 $$PID;
fi
}
trap finish EXIT;
However when I put a &
after the line python ...
I get an error
/bin/dash: Syntax error: ";" unexpected
How can this be done in a proper way?
EDIT
I have changed my makefile to do the following:
test::
python -m SimpleHTTPServer $(TEST_PORT) &
PID=$$(lsof -t -i @localhost:$(TEST_PORT) -sTCP:listen);
if [ -n "$$PID" ];
then
$(ENV_VARS) python test.py;
fi
function finish {
if [ -n "$$PID" ];
then
kill -9 $$PID;
fi
}
echo $$PID;
trap finish EXIT;
However I am getting an error: (without the line number)
/bin/dash: Syntax error: word unexpected
The important thing to remember here is that your line breaks don't actually exist when the shell sees the command.
So your first command becomes:
$(ENV_VARS) python -m SimpleHTTPServer $(TEST_PORT); PID=$$(lsof -t -i @localhost:$(TEST_PORT) -sTCP:listen); echo $(PID); if [ -n "$$PID" ]; then python test.py; fi; function finish { if [ -n "$$PID" ]; then kill -9 $$PID; fi } trap finish EXIT;
And your second command becomes:
PID=$$(lsof -t -i @localhost:$(TEST_PORT) -sTCP:listen); if [ -n "$$PID" ]; then $(ENV_VARS) python test.py; fi function finish { if [ -n "$$PID" ]; then kill -9 $$PID; fi } echo $$PID; trap finish EXIT;
Now those are both very hard to read so I don't expect you to spot the problem but the problem is that you are missing statement terminators in a few places.
Specifically:
Braces ( {}
) are word elements and so need spaces around them (and a terminator before, and after, the closing brace). You are missing those terminators here fi } trap
and here fi } echo
.
fi
is also not a statement terminator and so it needs one between it and the next statement. You are missing one here test.py; fi function
test.py; fi function
(as well as the ones in the braces from the first point).