Why "&" to run command in background does not work when the command is executed by spawnSync

100 Views Asked by At

I am trying to execute shell script via spawnSync where I need to run one of commands in background but the "&" seems just to be ignored.

My code:

spawnSync(`echo "*** Begin" && npm run startServer & echo "*** End"`, {
        stdio: ["ignore", "pipe", "inherit"],
        encoding: "utf-8",
        shell: true,
    });

From some reason, the command startServer is not executed in the background so second echo command is never executed.

Note: The script above is running as expected when I run it directly from bash.

EDIT: A little bit of clarification:

  • The command startServer will run forever as it is serving the server so it will never return under normal circumstances. From that reason, I need to run in background.
  • Originally, I had standard shell script (see below) which was working as expected. I thought that I will be able to execute more/less same script with spawnSync but it behaves differently.
    some commands
    some commands
    npm run startServer & 
    some commands
    ....
2

There are 2 best solutions below

2
rishi On

I'm not sure about the specifics of nodeJS and spawnSync, howver you essentially want to disassociate your server command from the current shell process.

You can achieve this by prepending your npm command with nohup

echo "*** Begin" && nohup npm run startServer & echo "*** End"

Since you're attempting to run the echo End command in parallel with your npm command, it will execute the end command right after the Begin. Further, it will keep the command running even after the terminal is killed.

0
Milan On

I found one alternative solution with using spawn for the serving server. . Not ideal as I need to break the origin script to smaller pieces.

spawnSync(`some command && some command`, {
        stdio: ["ignore", "pipe", "inherit"],
        encoding: "utf-8",
        shell: true,
}

const serverProcess = spawn(`npm run startServer`, {
        shell: true,
}); 

spawnSync(`another command && another command`, {
        stdio: ["ignore", "pipe", "inherit"],
        encoding: "utf-8",
        shell: true,
}

Anyway, I would like still know why & is not working in spawnSync