Як виконати команду оболонки в Javascript


127

Я хочу написати функцію JavaScript, яка виконає команди оболонки системи ( lsнаприклад) та поверне значення.

Як я цього досягти?


4
де ви хочете виконати цю команду на клієнті або на сервері?
Ян Ханчич

Яку операційну систему ви використовуєте?
Андерсон Грін

Ось підручник про те, як це зробити за допомогою node.js для сценарію оболонки: dreamsyssoft.com/javascript-shell-scripting/shell-tutorial.php
Rocky Pulley

7
Чому ви обрали найбільш неприємну відповідь як найкращу відповідь? o.0
Андре Леві

Будь ласка, уточнюйте, який тип javascript. Це можливо на JavaScript на стороні сервера, але неможливо на JavaScript на стороні клієнта.
Реймонд Пен

Відповіді:


132

Багато інших відповідей тут, схоже, вирішують це питання з точки зору функції JavaScript, що працює в браузері. Я зніму і відповім, припускаючи, що коли запитувач сказав "Сценарій оболонки", він мав на увазі JavaScript Node.js. Можливо, використовуючи command.js для використання кадру вашого коду :)

Ви можете використовувати модуль child_process з 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();

Сподіваюся, це допомагає!


14
За винятком однієї речі. Ви отримаєте помилку "дитина не є функцією". Виклик до exec () виконує команду - не потрібно викликати дочірню (). На жаль, зворотний виклик не викликається, коли дочірній процес має щось на виході - він викликається лише тоді, коли дочірній процес закінчується. Іноді це нормально, а іноді - ні.
Джон Дейган

2
Щоб уникнути зворотних дзвінків , ви можете використовувати execSync .
Дан Даскалеску

1
Хто говорив про браузер? Це говорить лише JavaScript, більше нічого.
Virus721

49

... через кілька років ...

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

3
Якщо вам потрібно лише виконати швидку команду, вся асинхроніка / очікування буде надмірна. Ви можете просто використовувати execSync .
Дан Даскалеску

Ніхто не просив рішення Node.js. Він говорить лише JavaScript.
Virus721

43

Я не знаю, чому попередні відповіді давали всілякі складні рішення. Якщо ви просто хочете виконати швидку команду, наприклад 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 функцію.


19

Це повністю залежить від середовища JavaScript. Будь ласка, докладно.

Наприклад, у Windows Scripting ви робите такі речі:

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

18
Чи можна зробити те ж саме в Unix-подібній операційній системі, такі як Linux?
Андерсон Грін

як ми виконуємо цю команду: print print -4 | знайти \ "адаптер TAP-Windows \" ?? Я намагався, але нічого не повертає
ikel

1
Ось що я шукав. Це дратує всіх тих, хто говорить про свій Node.js. Хто запитав тут Node.js? Ніхто цього не робив.
Virus721

Чи буде це працювати, якщо JavaScript знаходиться в браузері?
Алі Саджаджад

14

Коротко:

// 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
Здається, існує чимало рукодільниць, над якими веб-браузерами це працює, але люди повинні розуміти, що JavaScript - це також дійсно вірний сценарій мови оболонки Windows.
Крейг

6

З NodeJS просто так! І якщо ви хочете запустити цей скрипт під час кожного завантаження вашого сервера, ви можете ознайомитись із програмою вічно-сервісної служби !

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

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

Щоб уникнути зворотних дзвінків , для швидких команд можна використовувати execSync .
Дан Даскалеску

5

Примітка. Ці відповіді - від клієнта на базі браузера до веб-сервера на базі Unix.

Запустити команду на клієнті

Ви по суті не можете. Безпека говорить, що працювати лише в браузері, а доступ до команд та файлової системи обмежений.

Запустити ls на сервері

Ви можете використовувати дзвінок AJAX для отримання динамічної сторінки, що проходить у ваших параметрах, через GET.

Пам’ятайте, що це також відкриває ризик для безпеки, оскільки вам доведеться щось зробити для того, щоб mrs rouge hacker не отримав ваш додаток сказати run: / dev / null && rm -rf / ......

Тож у двох словах, біг від JS - це просто погана, погана ідея .... YMMV


Ви по суті не можете перехресно переглядати браузер. Я вважаю, що тільки IE має гачки в оболонці (через WSript / ActiveX).
Джастін Джонсон


3

У IE ви можете зробити це:

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

3

Ось проста команда, яка виконує ifconfigкоманду оболонки Linux

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

Щоб уникнути зворотних дзвінків , ви можете використовувати execSync .
Дан Даскалеску

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

Цю функцію можна легко використовувати, як:

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

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

1

З Nashorn ви можете написати такий сценарій:

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

і запустіть його:

jjs -scripting each_file.js

0

Якщо ви використовуєте npm, ви можете використовувати пакет shelljs

Щоб встановити: npm install [-g] shelljs

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

Дивіться більше: https://www.npmjs.com/package/shelljs

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.