It seems that sh do not treat ; as delimiter of command.
$ sh -c 'nohup ./server &; echo foo'
sh: -c: line 0: syntax error near unexpected token `;'
So, how to execute multiple commands from string with ampersand(background process)?
What you are after is what is called Asynchronous lists:
If a command is terminated by the control operator <ampersand> (
&), the shell shall execute the command asynchronously in a subshell. This means that the shell shall not wait for the command to finish before executing the next command.The format for running a command in the background is:
command1 & [command2 & ... ]source: POSIX.1-2017
The following example shows this behaviour:
sh -c "{ sleep 10 && echo foo ;} & echo bar"
This will execute echo bar and after 10 seconds, echo foo due to the command sleep 10 && echo foo. The latter is written as a compound command.
Thus, the solution is to remove the semi-column ; which is actually a sequential list. The reason why the original was failing is that you try to execute an empty command. This works:
sh -c "echo foo & echo bar ; echo car"
but this fails:
sh -c "echo foo & ; echo car"
as there is syntactically a command missing.
So in the end, the solution is simple:
sh -c 'nohup ./server & echo foo'