Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

152
Visualizações
Run bash in node js

I need to start the bash terminal, sequentially execute several commands, collect their results and quit. What is the correct way to do this in nodejs?

I tried to achieve this with child_process.spawn but it doesn't work as I have expected even with a single command.

Here is the simplified code:

const process = spawn(`bash`, [])

// wait for the process to spawn
await new Promise<void>(resolve => process.once(`spawn`, resolve))

// log any output (expected to be the current node version)
process.stdout.on(`data`, data => console.log(data))

// wait for "node --version" to execute
await new Promise<void>(resolve => process.stdin.write(`node --version\n`, `utf8`, () => resolve()))

// wait for the process to end
await new Promise<void>(resolve => process.once(`close`, resolve))

The problem here is that I do not receive any outputs in stdout while await process.once('spawn') works fine.

I have logged stderr and every other event like process.on and stdout.on('error') but they are all empty. So I'm wondering what is the problem here.

In addition, google has tons of examples on how to run a single command. But I need to run several in the same terminal, wait between each call and collect individual results from stdout. I'm not sure how to do this if this doesn't work as expected with the single command.

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Use shelljs package and implement a helper function to run each command. Helper function:

const shell = require('shelljs');

async function runShellCmd(cmd) {
  return new Promise((resolve, reject) => {
    shell.exec(cmd, async (code, stdout, stderr) => {
      if (!code) {
        return resolve(stdout);
      }
      return reject(stderr);
    });
  });
}

// run your commands here

In case of running multiple command in one instance, I would go with a .sh script:

  • You can also use output of one command for the next one. I found an example here: https://linuxhint.com/bash_command_output_variable/
  • You can also run node file.js to do additional processing (e.g. calculation, execute other commands, async/await queries) and then export the values needed for the environment to continue either via file or environment variables
about 4 years ago · Juan Pablo Isaza Relatório

0

There are two things that may cause the problem. First is the last code executes resolve() right away allowing for the code execution to move to the next instructions immediately. Second is console.log(data) might not be enough to print the output. As I observed it, data is a Buffer, and not a string.


Please try this code and see if you get any useful message:

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

async function main() {
  console.log("(console.log test)");
  const process = spawn(`bash`, [])

  // wait for the process to spawn
  await new Promise(resolve => process.once(`spawn`, resolve))

  // log any output (expected to be the current node version)
  process.stdout.on(`data`, data => console.log(data.toString()))
  
  // log any stderr
  process.stderr.on(`data`, data => console.log(data.toString()))

  // wait for "node --version" to execute
  await new Promise(resolve => process.stdin.write(`exec node --version\n`, `utf8`, () => resolve()))

  // wait for stdout and stderr stream to end, and process to close
  await Promise.all([
    new Promise(resolve => process.stdout.on('end', resolve)),
    new Promise(resolve => process.stderr.on('end', resolve)),
    new Promise(resolve => process.once(`close`, resolve))
  ])
}

main()
about 4 years ago · Juan Pablo Isaza Relatório

0

I'm not sure what the issue is, because I followed the docs, added a function returning a promise and it seems to work

I need to start the bash terminal, sequentially execute several commands, collect their results and quit

node when run is a process, bash when run is a process, ls when run is a process, rm when run is a process.. the terminal spawns processes from its command line interface and this below spawns processes from node(with the same text used in terminal)

let {spawn}=require('child_process') //spawn module
async function exec(command){
  return await new Promise(resolve=>{
    var toReturn="" //text to return
    let options={env:process.env,cwd:undefined,shell:true}
    let myChild=spawn(command,options)
    myChild.stdout.on('data',txt=>toReturn+=txt)
    myChild.stderr.on('data',txt=>toReturn+=txt)
    myChild.on('close',()=>resolve(toReturn))
  })
};
(async()=>{
  let ls_result=await exec('ls'), next_result=null
  if(someConditionBasedOn(ls_result)){next_result=await exec(if_true_cmd)}
  else{next_result=await exec(if_false_cmd)}
})()
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda