Как выполнить команду оболочки в Javascript



Я хочу написать функцию Javascript, которая будет выполнять команды системной оболочки (ls например) и возвращает значение.



Как мне этого добиться?

564   14  

14 ответов:

Что делать, если клиент, который вы выполняете этот javascript работает под управлением Windows? Это означает, что то, чего вы пытаетесь достичь, невозможно. Javascript является клиентским языком сценариев и работает в изолированной среде часто внутри веб-браузера, который предотвращает его доступ к ресурсам на компьютере.

многие другие ответы здесь, похоже, решают эту проблему с точки зрения функции JavaScript, запущенной в браузере. Я буду стрелять и отвечать, предполагая, что когда Аскер сказал "сценарий оболочки", он имел в виду узел.JS и серверной части на JavaScript. Возможно, используя командир.js чтобы использовать фрейм вашего кода:)

вы могли бы использовать child_proccess модуль из API узла. Я вставил пример кода ниже.

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

надеюсь, что это помогает!

...несколько лет спустя...

ES6 был принят в качестве стандарта и ES7 не за горами, поэтому он заслуживает обновленный ответ. Мы будем использовать ES6 + async/await с nodejs+babel в качестве примера, предварительные условия:

ваш пример foo.js файл может выглядеть так:

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

убедитесь, что у вас есть Бабель:

npm i babel-cli -g

установить последний пресет:

npm i babel-preset-latest

запустить его через:

babel-node --presets latest foo.js

в двух словах:

// 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");

это полностью зависит от среды JavaScript. Пожалуйста, уточните.

например, в сценариях Windows, вы делаете такие вещи, как:

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

С NodeJS просто так! И если вы хотите запустить этот скрипт при каждой загрузке вашего сервера, вы можете посмотреть на навсегда-службе приложение!

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

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

примечание: эти ответы от клиента на основе браузера к веб-серверу на основе Unix.

выполнить команду на клиенте

вы по существу не можете. Охрана говорит, что работать только в браузере и доступ к командам и файловая система общества.

запустить ls на сервере

вы можете использовать вызов AJAX для получения динамической страницы, передающей ваши параметры через GET.

имейте в виду, что это также открывает безопасность риск, поскольку вам нужно будет что-то сделать, чтобы убедиться, что mrs rouge hacker не заставит ваше приложение сказать run: /dev/null && rm-rf / ......

Так что в ореховой скорлупе, бег от JS - это просто плохая, плохая идея.... YMMV

еще один пост на эту тему с хорошим решением jQuery / Ajax / PHP:

сценарии оболочки и jQuery

в IE, вы можете сделать это :

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

С Насхорн вы можете написать такой скрипт:

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

и запустить его:

jjs -scripting each_file.js

вот простая команда, которая выполняет ifconfig команда оболочки Linux

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

Я не знаю, почему предыдущие ответы давали всевозможные сложные решения. Если вы просто хотите выполнить быструю команду ls, вам не нужно асинхронно/ждать или обратные вызовы или что-нибудь. Вот все, что вам нужно - 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);

для обработки ошибок, добавьте try/catch блок вокруг заявления.

если вы используете команду, которая занимает много времени для завершения, то да, посмотри асинхронные exec функция.

в java, в зависимости от привилегий:

Runtime run = Runtime.getRuntime();
Process pr = run.exec("ls");

pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));

String line = "";
while ((line=buf.readLine())!=null) {
    System.out.println(line);
}

в JavaScript, вы не можете. Они действительно две совершенно разные вещи.

EDIT

мой ответ был написан, когда этот вопрос в теги javaиjavascript. Поскольку OP, похоже, не делает различия, я не думаю, что могу точно сказать, что запрашивается здесь.

С помощью этого действия вы можете добиться успеха с вашим требованием,

  1. vim command.js
  2. копия Н мимо этого

#!/usr/bin/env node

function execute(command) {
  const exec = require('child_process').exec

  exec(command, (err, stdout, stderr) => {
    process.stdout.write(stdout)
  })
}

execute('echo "Hello World!"')
  1. node command.js

Comments

    Ничего не найдено.