Cách thực thi lệnh shell trong Javascript


127

Tôi muốn viết một hàm JavaScript sẽ thực thi các lệnh hệ thống ( lsví dụ) và trả về giá trị.

Làm thế nào để tôi đạt được điều này?


4
bạn muốn thực hiện lệnh này ở đâu, trên máy khách hay trên máy chủ?
Jan Hančič

Những hệ điều hành bạn đang sử dụng?
Anderson Green

Dưới đây là hướng dẫn về cách thực hiện bằng cách sử dụng node.js cho tập lệnh shell: dreamyssoft.com/javascript-shell-scripting/shell-tutorial.php
Triton Man

7
Tại sao bạn chọn câu trả lời không thích nhất là câu trả lời hay nhất? o.0
André Levy

Vui lòng cụ thể hơn về loại javascript. Điều này có thể trên javascript phía máy chủ nhưng không thể trên javascript phía máy khách.
Raymond Peng

Câu trả lời:


132

Nhiều câu trả lời khác ở đây dường như giải quyết vấn đề này từ góc độ của một hàm JavaScript đang chạy trong trình duyệt. Tôi sẽ bắn và trả lời giả sử rằng khi người hỏi nói "Shell Script", anh ta có nghĩa là JavaScript phụ trợ Node.js. Có thể sử dụng Commander.js để sử dụng khung mã của bạn :)

Bạn có thể sử dụng mô đun child_ process từ API của nút. Tôi dán mã ví dụ dưới đây.

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

Hi vọng điêu nay co ich!


14
Ngoại trừ một điều. Bạn sẽ nhận được lỗi "trẻ em không phải là một chức năng". Lệnh gọi exec () thực thi lệnh - không cần gọi child (). Thật không may, cuộc gọi lại không được gọi bất cứ khi nào tiến trình con có thứ gì đó xuất ra - nó chỉ được gọi khi tiến trình con thoát ra. Đôi khi điều đó ổn và đôi khi không.
John Deighan

2
Để tránh cuộc gọi lại, bạn có thể sử dụng execSync .
Dan Dascalescu

1
Ai đã nói về một trình duyệt? Nó chỉ nói JavaScript, không có gì hơn.
Virus721

49

... vài năm sau ...

ES6 đã được chấp nhận như là một tiêu chuẩn và ES7 đang ở một góc vì vậy nó xứng đáng được cập nhật câu trả lời. Chúng tôi sẽ sử dụng ES6 + async / await với nodejs + babel làm ví dụ, điều kiện tiên quyết là:

Tệp ví dụ của bạn foo.jscó thể trông như sau:

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

Hãy chắc chắn rằng bạn có babel:

npm i babel-cli -g

Cài đặt sẵn cài đặt mới nhất:

npm i babel-preset-latest

Chạy nó qua:

babel-node --presets latest foo.js

3
Nếu bạn chỉ cần thực hiện một lệnh nhanh, tất cả async / await là quá mức cần thiết. Bạn chỉ có thể sử dụng execSync .
Dan Dascalescu

Không ai yêu cầu một giải pháp Node.js. Nó chỉ nói JavaScript.
Virus721

43

Tôi không biết tại sao các câu trả lời trước lại đưa ra đủ loại giải pháp phức tạp. Nếu bạn chỉ muốn thực hiện một lệnh nhanh như thế nào ls, bạn không cần async / await hoặc callbacks hay bất cứ thứ gì. Đây là tất cả những gì bạn cần - 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);

Để xử lý lỗi, thêm một khối try/ catchxung quanh câu lệnh.

Nếu bạn đang chạy một lệnh mất nhiều thời gian để hoàn thành, thì có, hãy xem hàm không đồng bộexec .


19

Điều này phụ thuộc hoàn toàn vào môi trường JavaScript. Xin hãy giải thích.

Ví dụ: trong Windows Scripting, bạn làm những việc như:

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

18
Có thể làm điều tương tự trong một hệ điều hành giống Unix như Linux không?
Anderson Green

Làm thế nào để chúng ta chạy lệnh này: tuyến in -4 | tìm \ "Bộ điều hợp TAP-Windows \" ?? tôi đã cố gắng nhưng không trả lại được gì
ikel

1
Đó là những gì tôi đang tìm kiếm. Thật khó chịu khi tất cả những người nói về Node.js của họ. Ai đã yêu cầu Node.js ở đây? Không ai làm.
Virus721

14

Tóm lại:

// 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
Dường như có rất nhiều sự vặn vẹo về trình duyệt web này đang chạy, nhưng mọi người nên nhận ra rằng JavaScript cũng là một ngôn ngữ kịch bản lệnh shell Windows hoàn toàn hợp lệ.
Craig

6

Với NodeJS thì đơn giản như thế! Và nếu bạn muốn chạy tập lệnh này ở mỗi lần khởi động máy chủ của mình, bạn có thể xem ứng dụng này mãi mãi !

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

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

Để tránh các cuộc gọi lại, đối với các lệnh nhanh, bạn có thể sử dụng execSync .
Dan Dascalescu

5

Lưu ý: Những câu trả lời này là từ máy khách dựa trên trình duyệt đến máy chủ web dựa trên Unix.

Chạy lệnh trên máy khách

Bạn về cơ bản là không thể. Bảo mật cho biết chỉ chạy trong trình duyệt và quyền truy cập vào các lệnh và hệ thống tệp của nó bị hạn chế.

Chạy ls trên máy chủ

Bạn có thể sử dụng lệnh gọi AJAX để truy xuất một trang động chuyển các tham số của bạn thông qua GET.

Xin lưu ý rằng điều này cũng mở ra một rủi ro bảo mật vì bạn sẽ phải làm gì đó để đảm bảo rằng mrs rouge hacker không khiến ứng dụng của bạn phải chạy: / dev / null && rm -rf / ......

Vì vậy, tóm lại, chạy từ JS chỉ là một ý tưởng tồi, tồi tệ .... YMMV


Về cơ bản, bạn không thể theo cách đa trình duyệt. Tôi tin rằng chỉ IE có hook vào shell (thông qua WSript / ActiveX).
Justin Johnson


3

Trong IE, bạn có thể làm điều này:

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

3

Đây là lệnh đơn giản thực thi ifconfiglệnh shell của Linux

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

Để tránh cuộc gọi lại, bạn có thể sử dụng execSync .
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);
}

Chức năng này có thể dễ dàng được sử dụng như:

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

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

1

Với nashorn bạn có thể viết một kịch bản như thế này:

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

và chạy nó:

jjs -scripting each_file.js

0

Nếu bạn đang sử dụng npm, bạn có thể sử dụng gói shelljs

Để cài đặt: npm install [-g] shelljs

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

Xem thêm: https://www.npmjs.com/package/shelljs

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.