Como executar o comando shell em Javascript


127

Quero escrever uma função JavaScript que execute os comandos do shell do sistema (ls por exemplo) e retorne o valor.

Como faço para conseguir isso?


4
onde você gostaria de executar este comando, no cliente ou no servidor?
Jan Hančič

Qual sistema operacional você está usando?
Anderson Green

Aqui está um tutorial sobre como fazê-lo usando node.js para um script shell: dreamsyssoft.com/javascript-shell-scripting/shell-tutorial.php
Rocky Pulley

7
Por que você escolheu a resposta mais odiada como a melhor resposta? o.0
André Levy

Por favor, seja mais específico sobre que tipo de javascript. Isso é possível no javascript do servidor, mas impossível no javascript do cliente.
Raymond Peng

Respostas:


132

Muitas das outras respostas aqui parecem abordar esse problema da perspectiva de uma função JavaScript em execução no navegador. Vou filmar e responder assumindo que, quando o solicitante disse "Shell Script", ele quis dizer um JavaScript para o Node.js. Possivelmente usando commander.js para enquadrar seu código :)

Você pode usar o módulo child_process da API do nó. Colei o código de exemplo abaixo.

var exec = require('child_process').exec, child;

child = exec('cat *.js bad_file | wc -l',
    function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
             console.log('exec error: ' + error);
        }
    });
 child();

Espero que isto ajude!


14
Exceto por uma coisa. Você receberá o erro "filho não é uma função". A chamada para exec () executa o comando - não é necessário chamar child (). Infelizmente, o retorno de chamada não é chamado sempre que o processo filho tiver algo para produzir - é chamado apenas quando o processo filho sai. Às vezes, tudo bem e às vezes não.
precisa saber é o seguinte

2
Para evitar retornos de chamada, você pode usar execSync .
Dan Dascalescu

1
Quem falou sobre um navegador? Diz apenas JavaScript, nada mais.
Virus721 10/03

49

... alguns anos depois ...

O ES6 foi aceito como padrão e o ES7 está chegando, por isso merece resposta atualizada. Usaremos o ES6 + async / waitit com nodejs + babel como exemplo, os pré-requisitos são:

Seu foo.jsarquivo de exemplo pode parecer com:

import { exec } from 'child_process';

/**
 * Execute simple shell command (async wrapper).
 * @param {String} cmd
 * @return {Object} { stdout: String, stderr: String }
 */
async function sh(cmd) {
  return new Promise(function (resolve, reject) {
    exec(cmd, (err, stdout, stderr) => {
      if (err) {
        reject(err);
      } else {
        resolve({ stdout, stderr });
      }
    });
  });
}

async function main() {
  let { stdout } = await sh('ls');
  for (let line of stdout.split('\n')) {
    console.log(`ls: ${line}`);
  }
}

main();

Certifique-se de ter babel:

npm i babel-cli -g

Instale a última predefinição:

npm i babel-preset-latest

Execute-o via:

babel-node --presets latest foo.js

3
Se você precisar apenas executar um comando rápido, todo o assíncrono / espera será um exagero. Você pode apenas usar execSync .
Dan Dascalescu

Ninguém pediu uma solução para o Node.js. Diz apenas JavaScript.
Virus721 10/03

43

Não sei por que as respostas anteriores deram todos os tipos de soluções complicadas. Se você deseja apenas executar um comando rápido como ls, não precisa de assíncrono / espera ou retorno de chamada ou qualquer coisa. Aqui está tudo o que você precisa - execSync :

const execSync = require('child_process').execSync;
// import { execSync } from 'child_process';  // replace ^ if using ES modules
const output = execSync('ls', { encoding: 'utf-8' });  // the default is 'buffer'
console.log('Output was:\n', output);

Para tratamento de erros, adicione um bloco try/ catchao redor da instrução.

Se você estiver executando um comando que demora muito para concluir, sim, observe a função assíncronaexec .


19

Isso depende inteiramente do ambiente JavaScript. Por favor elabore.

Por exemplo, no Windows Scripting, você faz coisas como:

var shell = WScript.CreateObject("WScript.Shell");
shell.Run("command here");

18
É possível fazer a mesma coisa em um sistema operacional semelhante ao Unix, como o Linux?
Anderson Green

como executamos este comando: route print -4 | encontre \ "Adaptador TAP-Windows \" ?? Eu tentei, mas retorna nada
ikel

1
Era isso que eu estava procurando. É chato todas aquelas pessoas falando sobre seus Node.js. Quem pediu o Node.js aqui? Ninguém fez.
Virus721 10/03

Isso funcionaria se o JavaScript estivesse dentro de um navegador?
Ali Sajjad

14

Em poucas palavras:

// Instantiate the Shell object and invoke its execute method.
var oShell = new ActiveXObject("Shell.Application");

var commandtoRun = "C:\\Winnt\\Notepad.exe";
if (inputparms != "") {
  var commandParms = document.Form1.filename.value;
}

// Invoke the execute method.  
oShell.ShellExecute(commandtoRun, commandParms, "", "open", "1");


5
Parece haver muita confusão sobre qual navegador da Web está sendo executado, mas as pessoas devem perceber que o JavaScript também é uma linguagem de script de shell do Windows perfeitamente válida.
Craig

6

Com o NodeJS é simples assim! E se você deseja executar esse script em cada inicialização do seu servidor, pode dar uma olhada no aplicativo de serviço permanente !

var exec = require('child_process').exec;

exec('php main.php', function (error, stdOut, stdErr) {
    // do what you want!
});

Para evitar retornos de chamada, para comandos rápidos, você pode usar execSync .
Dan Dascalescu 30/09/19

5

Nota: Essas respostas são de um cliente baseado em navegador para um servidor Web baseado em Unix.

Executar comando no cliente

Você essencialmente não pode. A segurança diz que apenas é executado em um navegador e seu acesso a comandos e sistema de arquivos é limitado.

Execute ls no servidor

Você pode usar uma chamada AJAX para recuperar uma página dinâmica passando seus parâmetros por meio de um GET.

Esteja ciente de que isso também abre um risco de segurança, pois você teria que fazer algo para garantir que o Sr. Rouge Hacker não faça com que seu aplicativo diga execute: / dev / null && rm -rf / ......

Então, resumindo, correr de JS é apenas uma péssima idéia ... YMMV


Você não pode, essencialmente, de maneira cruzada no navegador. Eu acredito que apenas o IE tem ganchos no shell (via WSript / ActiveX).
Justin Johnson


3

No IE, você pode fazer isso:

var shell = new ActiveXObject("WScript.Shell");
shell.run("cmd /c dir & pause");

3

Aqui está um comando simples que executa o ifconfigcomando shell do Linux

var process = require('child_process');
process.exec('ifconfig',function (err,stdout,stderr) {
    if (err) {
        console.log("\n"+stderr);
    } else {
        console.log(stdout);
    }
});

Para evitar retornos de chamada, você pode usar execSync .
Dan Dascalescu

3
function exec(cmd, handler = function(error, stdout, stderr){console.log(stdout);if(error !== null){console.log(stderr)}})
{
    const childfork = require('child_process');
    return childfork.exec(cmd, handler);
}

Esta função pode ser facilmente usada como:

exec('echo test');
//output:
//test

exec('echo test', function(err, stdout){console.log(stdout+stdout+stdout)});
//output:
//testtesttest

1

Com o nashorn, você pode escrever um script como este:

$EXEC('find -type f');
var files = $OUT.split('\n');
files.forEach(...
...

e execute:

jjs -scripting each_file.js

0

Se você estiver usando o npm, poderá usar o pacote shelljs

Para instalar: npm install [-g] shelljs

var shell = require('shelljs');
shell.ls('*.js').forEach(function (file) {
// do something
});

Veja mais: https://www.npmjs.com/package/shelljs

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.