Comment exécuter la commande shell en Javascript


127

Je veux écrire une fonction JavaScript qui exécutera les commandes du shell système ( lspar exemple) et retournera la valeur.

Comment y parvenir?


4
où souhaitez-vous exécuter cette commande, sur le client ou sur le serveur?
Jan Hančič

Quel système d'exploitation utilisez-vous?
Anderson Green

Voici un tutoriel sur la façon de le faire en utilisant node.js pour un script shell: dreamyssoft.com/javascript-shell-scripting/shell-tutorial.php
Rocky Pulley

7
Pourquoi avez-vous choisi la réponse la plus détestée comme meilleure réponse? o.0
André Levy

Veuillez être plus précis sur le type de javascript. Ceci est possible sur javascript côté serveur mais impossible sur javascript côté client.
Raymond Peng

Réponses:


132

La plupart des autres réponses ici semblent aborder ce problème du point de vue d'une fonction JavaScript exécutée dans le navigateur. Je vais tirer et répondre en supposant que lorsque le demandeur a dit "Shell Script", il voulait dire un JavaScript backend Node.js. Peut-être utiliser commander.js pour utiliser frame votre code :)

Vous pouvez utiliser le module child_process de l'API du nœud. J'ai collé l'exemple de code ci-dessous.

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();

J'espère que cela t'aides!


14
Sauf pour une chose. Vous obtiendrez l'erreur "l'enfant n'est pas une fonction". L'appel à exec () exécute la commande - pas besoin d'appeler child (). Malheureusement, le rappel n'est pas appelé chaque fois que le processus enfant a quelque chose à sortir - il n'est appelé que lorsque le processus enfant se termine. Parfois ça va et parfois non.
John Deighan

2
Pour éviter les rappels, vous pouvez utiliser execSync .
Dan Dascalescu

1
Qui a parlé d'un navigateur? Il ne dit que JavaScript, rien de plus.
Virus721

49

... quelques années plus tard ...

ES6 a été accepté comme standard et ES7 est au coin de la rue, il mérite donc une réponse mise à jour. Nous utiliserons ES6 + async / await avec nodejs + babel comme exemple, les prérequis sont:

Votre foo.jsfichier d' exemple peut ressembler à:

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();

Assurez-vous d'avoir babel:

npm i babel-cli -g

Installez le dernier préréglage:

npm i babel-preset-latest

Exécutez-le via:

babel-node --presets latest foo.js

3
Si vous avez seulement besoin d'exécuter une commande rapide, tout l'async / wait est exagéré. Vous pouvez simplement utiliser execSync .
Dan Dascalescu

Personne n'a demandé une solution Node.js. Il ne dit que JavaScript.
Virus721

43

Je ne sais pas pourquoi les réponses précédentes ont donné toutes sortes de solutions compliquées. Si vous voulez simplement exécuter une commande rapide comme ls, vous n'avez pas besoin d'async / await ou de rappels ou quoi que ce soit. Voici tout ce dont vous avez besoin - 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);

Pour la gestion des erreurs, ajoutez un bloc try/ catchautour de l'instruction.

Si vous exécutez une commande qui prend beaucoup de temps, alors oui, regardez la fonction asynchroneexec .


19

Cela dépend entièrement de l'environnement JavaScript. Veuillez préciser.

Par exemple, dans Windows Scripting, vous faites des choses comme:

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

18
Est-il possible de faire la même chose dans un système d'exploitation de type Unix tel que Linux?
Anderson Green

comment exécuter cette commande: route print -4 | trouver \ "Adaptateur TAP-Windows \" ?? J'ai essayé mais ne retourne rien
ikel

1
C'est ce que je cherchais. C'est ennuyeux tous ces gens qui parlent de leur Node.js. Qui a demandé Node.js ici? Personne ne l'a fait.
Virus721

Cela fonctionnerait-il si JavaScript se trouve dans un navigateur?
Ali Sajjad

14

En un mot:

// 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
Il semble y avoir beaucoup de malentendus sur le navigateur Web dans lequel il s'exécute, mais les gens doivent se rendre compte que JavaScript est également un langage de script de shell Windows parfaitement valide.
Craig

6

Avec NodeJS, c'est simple comme ça! Et si vous souhaitez exécuter ce script à chaque démarrage de votre serveur, vous pouvez jeter un œil sur l' application pour toujours !

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

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

Pour éviter les rappels, pour les commandes rapides, vous pouvez utiliser execSync .
Dan Dascalescu

5

Remarque: ces réponses proviennent d'un client basé sur un navigateur vers un serveur Web basé sur Unix.

Exécuter la commande sur le client

Vous ne pouvez essentiellement pas. La sécurité dit ne fonctionner que dans un navigateur et son accès aux commandes et au système de fichiers est limité.

Exécutez ls sur le serveur

Vous pouvez utiliser un appel AJAX pour récupérer une page dynamique en passant vos paramètres via un GET.

Sachez que cela présente également un risque de sécurité car vous auriez à faire quelque chose pour vous assurer que mrs rouge hacker ne fasse pas dire à votre application run: / dev / null && rm -rf / ......

Donc en un mot, courir à partir de JS est juste une mauvaise, une mauvaise idée ... YMMV


Vous ne pouvez essentiellement pas de manière multi-navigateurs. Je crois que seul IE a des crochets dans le shell (via WSript / ActiveX).
Justin Johnson


3

Dans IE, vous pouvez faire ceci:

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

3

Voici une commande simple qui exécute la ifconfigcommande shell de Linux

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

Pour éviter les rappels, vous pouvez utiliser 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);
}

Cette fonction peut être facilement utilisée comme:

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

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

1

Avec nashorn, vous pouvez écrire un script comme celui-ci:

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

et exécutez-le:

jjs -scripting each_file.js

0

Si vous utilisez npm, vous pouvez utiliser le package shelljs

À installer: npm install [-g] shelljs

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

En savoir plus: https://www.npmjs.com/package/shelljs

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.