Як виконати команду оболонки в 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.