Spawning top with arguments and parsing with grep

I want to spawn top with a few arguments to get the current cpu load & usage.
If I type the full command on my ssh session top -bn1 | grep "Cpu(s)|top -", I get the complete and working response.
But how is the correct way to spawn this command with execFile?

This is what I want to do:

import childProcess from 'child_process'
import util from 'util'

const execFile = util.promisify(childProcess.execFile)

async function getData() {
    // Not working
    const command = 'top -bn1 | grep "Cpu(s)|top -"'
    const args = []
    
    // Also tried this
    const command = 'top'
    const args = ['-bn1 | grep "Cpu(s)|top -"']
    
    const { stdout } = await execFile(command, args, { maxBuffer: 1000 * 1000 * 10 })
    console.log(stdout)
}
getData()

But the spawn will fail with the following error:

Error: spawn top -bn1 | grep "Cpu(s)|top -" ENOENT
    at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19)
    at onErrorNT (node:internal/child_process:480:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn top -bn1 | grep "Cpu(s)|top -"',
  path: 'top -bn1 | grep "Cpu(s)|top -"',
  spawnargs: [],
  cmd: 'top -bn1 | grep "Cpu(s)|top -"',
  stdout: '',
  stderr: ''
}

Answer

I didn’t know you cant combine multiple commands (piped commands) in a single execFile. But you can use the shell option.

My solution right now is using the shell option:

const command = 'top -bn1 | grep "Cpu(s)|top -"'
const args = []
const { stdout } = await execFile(command, args, { shell: true, maxBuffer: 1000 * 1000 * 10 })

Alternatively, you can pipe stdout into a second spawn (pipe into grep), but this would be a little too much for my simple task.