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?

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

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

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

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

Ein weiterer Beitrag zu diesem Thema mit einer netten jQuery / Ajax / PHP-Lösung:

Shell-Scripting und jQuery

August
quelle
3

Im IE können Sie dies tun:

var shell = new ActiveXObject("WScript.Shell");
shell.run("cmd /c dir & pause");
Nonozor
quelle
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);
    }
});
Anup Panwar
quelle
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
AliFurkan
quelle
1

Mit nashorn können Sie ein Skript wie folgt schreiben:

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

und führen Sie es aus:

jjs -scripting each_file.js
Maciek Łoziński
quelle
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

Emma
quelle