Running shell commands using child processes in Node.js

When building applications with Node.js, there may be a need to execute shell commands from within your application. This could be for tasks like running system commands, executing scripts, or interacting with external dependencies. Node.js provides a built-in module called child_process that allows you to run shell commands and capture their output.

Using the child_process module

To use the child_process module in Node.js, you need to require it first:

const { exec } = require('child_process');

The exec function in the child_process module creates a new shell process and runs the provided command inside it. Here’s a simple example of running a shell command using exec:

exec('ls -l', (error, stdout, stderr) => {
  if (error) {
    console.error(`Error executing command: ${error}`);
    return;
  }

  console.log(`Command output:\n ${stdout}`);
  console.error(`Command errors:\n ${stderr}`);
});

In this example, we’re using the ls -l command to list the files and directories in the current directory. The exec function takes a command as its first argument and a callback function as its second argument. The callback function is invoked when the command execution is complete, and it receives three parameters: error, stdout (standard output), and stderr (standard error).

Running shell commands with options

The exec function allows you to specify additional options when running shell commands. For example, you can set the current working directory, pass environment variables, or specify a timeout for command execution. Here’s an example that demonstrates some of these options:

const options = {
  cwd: '/path/to/directory', // Set the current working directory of the shell command
  env: { NODE_ENV: 'production' }, // Pass environment variables
  timeout: 5000, // Set a timeout for command execution (in milliseconds)
};

exec('npm install', options, (error, stdout, stderr) => {
  // Handle the command output and errors
});

Spawning long-running processes

If you need to execute long-running processes that produce continuous output, the spawn function is a better option than exec. The spawn function creates a child process that remains open for communication. You can read the output of the child process or send input to it.

Here’s a basic example of using spawn to run a long-running process and read its output:

const { spawn } = require('child_process');

const process = spawn('node', ['myScript.js']);

process.stdout.on('data', (data) => {
  console.log(`Process output: ${data}`);
});

process.stderr.on('data', (data) => {
  console.error(`Process error: ${data}`);
});

process.on('close', (code) => {
  console.log(`Process exited with code ${code}`);
});

In this example, we’re spawning a Node.js script called myScript.js. The spawn function takes the command to run as its first argument and an array of command-line arguments as its second argument.

Conclusion

The child_process module in Node.js provides a powerful way to run shell commands from within your applications. Whether you need to execute short-lived commands or long-running processes, the built-in functions like exec and spawn allow you to run shell commands seamlessly. By using the functionality provided by the child_process module, you can extend the capabilities of your Node.js applications and integrate with the underlying system.