Ausführen eines Shell-Befehls in Javascript


127

Ich möchte eine JavaScript-Funktion schreiben, die ( lszum Beispiel) die System-Shell-Befehle ausführt und den Wert zurückgibt.

Wie erreiche ich das?


4
Wo möchten Sie diesen Befehl auf dem Client oder auf dem Server ausführen?
Jan Hančič

Welches Betriebssystem verwenden Sie?
Anderson Green

Hier ist ein Tutorial, wie man es mit node.js für ein Shell-Skript macht: dreamsyssoft.com/javascript-shell-scripting/shell-tutorial.php
Triton Man

7
Warum haben Sie die unbeliebteste Antwort als die beste Antwort gewählt? o.0
André Levy

Bitte geben Sie genauer an, welche Art von Javascript verwendet wird. Dies ist auf serverseitigem Javascript möglich, auf clientseitigem Javascript jedoch nicht.
Raymond Peng

Antworten:


132

Viele der anderen Antworten hier scheinen dieses Problem aus der Perspektive einer JavaScript-Funktion zu lösen, die im Browser ausgeführt wird. Ich werde schießen und antworten, vorausgesetzt, als der Fragesteller "Shell Script" sagte, meinte er ein Node.js Backend JavaScript. Verwenden Sie möglicherweise Commander.js , um Ihren Code zu rahmen :)

Sie können das Modul child_process über die API des Knotens verwenden. Ich habe den folgenden Beispielcode eingefügt.

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

Hoffe das hilft!


14
Außer eine Sache. Sie erhalten die Fehlermeldung "Kind ist keine Funktion". Der Aufruf von exec () führt den Befehl aus - es ist nicht erforderlich, child () aufzurufen. Leider wird der Rückruf nicht aufgerufen, wenn der untergeordnete Prozess etwas auszugeben hat - er wird nur aufgerufen, wenn der untergeordnete Prozess beendet wird. Manchmal ist das in Ordnung und manchmal nicht.
John Deighan

2
Um Rückrufe zu vermeiden, können Sie execSync verwenden .
Dan Dascalescu

1
Wer hat über einen Browser gesprochen? Es heißt nur JavaScript, nichts weiter.
Virus721

49

... einige Jahre später ...

ES6 wurde als Standard akzeptiert und ES7 steht vor der Tür, daher verdient es eine aktualisierte Antwort. Wir werden ES6 + async / await mit nodejs + babel als Beispiel verwenden. Voraussetzungen sind:

Ihre Beispieldatei foo.jskönnte folgendermaßen aussehen:

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

Stellen Sie sicher, dass Sie babel haben:

npm i babel-cli -g

Installieren Sie die neueste Voreinstellung:

npm i babel-preset-latest

Führen Sie es aus über:

babel-node --presets latest foo.js

3
Wenn Sie nur einen Schnellbefehl ausführen müssen, ist alles Async / Warten auf Overkill. Sie können einfach execSync verwenden .
Dan Dascalescu

Niemand fragte nach einer Node.js-Lösung. Es heißt nur JavaScript.
Virus721

43

Ich weiß nicht, warum die vorherigen Antworten alle möglichen komplizierten Lösungen lieferten. Wenn Sie nur einen schnellen Befehl wie ausführen möchten, lsbenötigen Sie weder Async / Warten noch Rückrufe oder ähnliches . Hier ist alles was Sie brauchen - 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);

Fügen Sie zur Fehlerbehandlung einen try/ catch-Block um die Anweisung hinzu.

Wenn Sie einen Befehl ausführen, dessen Ausführung lange dauert, sehen Sie sich die asynchroneexec Funktion an.


19

Dies hängt vollständig von der JavaScript-Umgebung ab. Bitte erläutern Sie.

In Windows Scripting führen Sie beispielsweise folgende Aktionen aus:

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

18
Ist es möglich, dasselbe in einem Unix-ähnlichen Betriebssystem wie Linux zu tun?
Anderson Green

Wie führen wir diesen Befehl aus: route print -4 | Finden Sie "TAP-Windows Adapter"? Ich habe es versucht, aber nichts zurückgegeben
Ikel

1
Das habe ich gesucht. Es nervt all die Leute, die über ihre Node.js sprechen. Wer hat hier nach Node.js gefragt? Niemand tat es.
Virus721

14

In einer Nussschale:

// 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
Es scheint eine Menge Handarbeit darüber zu geben, in welchem ​​Webbrowser dies ausgeführt wird, aber die Leute sollten sich darüber im Klaren sein, dass JavaScript auch eine perfekt gültige Windows-Shell-Skriptsprache ist.
Craig

6

Mit NodeJS ist das ganz einfach! Und wenn Sie dieses Skript bei jedem Start Ihres Servers ausführen möchten, können Sie sich die Forever-Service- Anwendung ansehen !

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

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

Um Rückrufe zu vermeiden, können Sie für schnelle Befehle execSync verwenden .
Dan Dascalescu

5

Hinweis: Diese Antworten stammen von einem browserbasierten Client an einen Unix-basierten Webserver.

Führen Sie den Befehl auf dem Client aus

Sie können im Wesentlichen nicht. Laut Sicherheit wird nur in einem Browser ausgeführt und der Zugriff auf Befehle und Dateisystem ist eingeschränkt.

Führen Sie ls auf dem Server aus

Sie können einen AJAX-Aufruf verwenden, um eine dynamische Seite abzurufen, die Ihre Parameter über ein GET übergibt.

Beachten Sie, dass dies auch ein Sicherheitsrisiko darstellt, da Sie etwas tun müssten, um sicherzustellen, dass Frau Rouge Hacker Ihre Anwendung nicht zum Ausführen bringt: / dev / null && rm -rf / ......

Kurz gesagt, es ist nur eine schlechte, schlechte Idee, vor JS davonzulaufen ... YMMV


Sie können im Wesentlichen nicht browserübergreifend. Ich glaube, nur IE hat Hooks in die Shell (über WSript / ActiveX).
Justin Johnson


3

Im IE können Sie dies tun:

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

3

Hier ist ein einfacher Befehl, der den ifconfigShell-Befehl von Linux ausführt

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

Um Rückrufe zu vermeiden, können Sie execSync verwenden .
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);
}

Diese Funktion kann einfach verwendet werden wie:

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

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


0

Wenn Sie npm verwenden, können Sie das Paket shelljs verwenden

Installieren: npm install [-g] shelljs

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

Weitere Informationen: https://www.npmjs.com/package/shelljs

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.