Cara menjalankan perintah shell di Javascript

127

Saya ingin menulis fungsi JavaScript yang akan menjalankan perintah shell sistem ( lsmisalnya) dan mengembalikan nilainya.

Bagaimana saya mencapai ini?

Sunil Kumar Sahoo
sumber
4
di mana Anda ingin menjalankan perintah ini, di klien atau di server?
Jan Hančič
sistem operasi yang Anda gunakan?
Anderson Green
Berikut adalah tutorial tentang cara melakukannya dengan menggunakan node.js untuk skrip shell: dreamsyssoft.com/javascript-shell-scripting/shell-tutorial.php
Rocky Pulley
7
Mengapa Anda memilih jawaban yang paling tidak disukai sebagai jawaban terbaik? o.0
André Levy
Harap lebih spesifik tentang jenis javascript. Ini dimungkinkan pada javascript sisi server tetapi tidak mungkin pada javascript sisi klien.
Raymond Peng

Jawaban:

132

Banyak dari jawaban lain di sini tampaknya mengatasi masalah ini dari perspektif fungsi JavaScript yang berjalan di browser. Saya akan menembak dan menjawab dengan asumsi bahwa ketika penanya mengatakan "Shell Script" yang dia maksud adalah JavaScript backend Node.js. Mungkin menggunakan commander.js untuk menggunakan bingkai kode Anda :)

Anda dapat menggunakan modul child_process dari node API. Saya menempelkan kode contoh di bawah ini.

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

Semoga ini membantu!

Josh
sumber
14
Kecuali satu hal. Anda akan mendapatkan pesan kesalahan "anak bukan fungsi". Panggilan ke exec () menjalankan perintah - tidak perlu memanggil child (). Sayangnya, callback tidak dipanggil setiap kali proses anak memiliki sesuatu untuk dikeluarkan - dipanggil hanya ketika proses anak keluar. Terkadang tidak apa-apa dan terkadang tidak.
John Deighan
2
Untuk menghindari callback, Anda bisa menggunakan execSync .
Dan Dascalescu
1
Siapa yang berbicara tentang browser? Itu hanya mengatakan JavaScript, tidak lebih.
Virus721
49

... beberapa tahun kemudian ...

ES6 telah diterima sebagai standar dan ES7 sudah dekat sehingga layak mendapatkan jawaban yang diperbarui. Kami akan menggunakan ES6 + async / await dengan nodejs + babel sebagai contoh, prasyaratnya adalah:

foo.jsFile contoh Anda mungkin terlihat seperti ini:

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

Pastikan Anda memiliki babel:

npm i babel-cli -g

Instal preset terbaru:

npm i babel-preset-latest

Jalankan melalui:

babel-node --presets latest foo.js
Mirek Rusin
sumber
3
Jika Anda hanya perlu menjalankan perintah cepat, semua async / await sudah berlebihan. Anda bisa menggunakan execSync .
Dan Dascalescu
Tidak ada yang meminta solusi Node.js. Itu hanya mengatakan JavaScript.
Virus721
43

Saya tidak tahu mengapa jawaban sebelumnya memberikan segala macam solusi yang rumit. Jika Anda hanya ingin menjalankan perintah cepat seperti ls, Anda tidak perlu async / await atau callback atau apa pun. Ini semua yang Anda butuhkan - 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);

Untuk penanganan kesalahan, tambahkan try/ catchblok di sekitar pernyataan.

Jika Anda menjalankan perintah yang membutuhkan waktu lama untuk menyelesaikannya, ya, lihat fungsi asynchronousexec .

Dan Dascalescu
sumber
19

Ini sepenuhnya bergantung pada lingkungan JavaScript. Tolong jelaskan.

Misalnya, di Windows Scripting, Anda melakukan hal-hal seperti:

var shell = WScript.CreateObject("WScript.Shell");
shell.Run("command here");
Matt
sumber
18
Apakah mungkin melakukan hal yang sama di sistem operasi mirip Unix seperti Linux?
Anderson Green
bagaimana kita menjalankan perintah ini: route print -4 | temukan \ "TAP-Windows Adapter \" ?? saya mencoba tetapi tidak mengembalikan apa
ikel
1
Itulah yang saya cari. Menjengkelkan semua orang yang membicarakan Node.js. Siapa yang meminta Node.js di sini? Tidak ada yang melakukannya.
Virus721
Apakah ini akan berfungsi jika JavaScript ada di dalam browser?
Ali Sajjad
14

Pendeknya:

// 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
sumber
5
Tampaknya ada banyak masalah di mana browser web ini dijalankan, tetapi orang-orang harus menyadari bahwa JavaScript juga merupakan bahasa skrip shell Windows yang valid.
Craig
6

Dengan NodeJS sesederhana itu! Dan jika Anda ingin menjalankan skrip ini di setiap boot server Anda, Anda dapat melihat aplikasi layanan selamanya !

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

exec('php main.php', function (error, stdOut, stdErr) {
    // do what you want!
});
keupsonite
sumber
Untuk menghindari callback, untuk perintah cepat Anda bisa menggunakan execSync .
Dan Dascalescu
5

Catatan: Jawaban ini berasal dari klien berbasis browser ke server web berbasis Unix.

Jalankan perintah pada klien

Anda pada dasarnya tidak bisa. Keamanan mengatakan hanya berjalan di dalam browser dan aksesnya ke perintah dan sistem file dibatasi.

Jalankan ls di server

Anda dapat menggunakan panggilan AJAX untuk mengambil halaman dinamis yang meneruskan parameter Anda melalui GET.

Ketahuilah bahwa ini juga membuka risiko keamanan karena Anda harus melakukan sesuatu untuk memastikan bahwa mrs rouge hacker tidak membuat aplikasi Anda mengatakan run: / dev / null && rm -rf / ......

Singkatnya, menjalankan dari JS hanyalah ide yang buruk dan buruk .... YMMV

Wayne
sumber
Anda pada dasarnya tidak dapat melakukannya dengan cara lintas-browser. Saya percaya hanya IE yang memiliki kait ke shell (melalui WSript / ActiveX).
Justin Johnson
3

Posting lain tentang topik ini dengan solusi jQuery / Ajax / PHP yang bagus:

shell scripting dan jQuery

Agustus
sumber
3

Di IE, Anda dapat melakukan ini:

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

Berikut adalah perintah sederhana yang menjalankan ifconfigperintah shell Linux

var process = require('child_process');
process.exec('ifconfig',function (err,stdout,stderr) {
    if (err) {
        console.log("\n"+stderr);
    } else {
        console.log(stdout);
    }
});
Anup Panwar
sumber
Untuk menghindari callback, Anda bisa menggunakan 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);
}

Fungsi ini dapat digunakan dengan mudah seperti:

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

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

Dengan nashorn Anda dapat menulis skrip seperti ini:

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

dan jalankan:

jjs -scripting each_file.js
Maciek Łoziński
sumber
0

Jika Anda menggunakan npm, Anda dapat menggunakan paket shelljs

Untuk memasang: npm install [-g] shelljs

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

Lihat lebih lanjut: https://www.npmjs.com/package/shelljs

Emma
sumber