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?

Sunil Kumar Sahoo
fonte
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!

Josh
fonte
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
Mirek Rusin
fonte
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 .

Dan Dascalescu
fonte
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");
Matt
fonte
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");
Dana
fonte
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!
});
keupsonite
fonte
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

Wayne
fonte
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

Outro post sobre este tópico com uma boa solução jQuery / Ajax / PHP:

scripts de shell e jQuery

agosto
fonte
3

No IE, você pode fazer isso:

var shell = new ActiveXObject("WScript.Shell");
shell.run("cmd /c dir & pause");
nonozor
fonte
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);
    }
});
Anup Panwar
fonte
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
AliFurkan
fonte
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
Maciek Łoziński
fonte
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

Emma
fonte