Chcę napisać funkcję JavaScript, która wykona polecenia powłoki systemu ( lsna przykład) i zwróci wartość.
Jak to osiągnąć?
Chcę napisać funkcję JavaScript, która wykona polecenia powłoki systemu ( lsna przykład) i zwróci wartość.
Jak to osiągnąć?
Odpowiedzi:
Wydaje się, że wiele innych odpowiedzi tutaj rozwiązuje ten problem z perspektywy funkcji JavaScript działającej w przeglądarce. Strzelę i odpowiem zakładając, że kiedy pytający powiedział „Skrypt powłoki”, miał na myśli JavaScript zaplecza Node.js. Możliwe, że używasz commander.js do ramki swojego kodu :)
Możesz użyć modułu child_process z interfejsu API węzła. Wkleiłem poniższy przykładowy kod.
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();
Mam nadzieję że to pomoże!
... kilka lat później ...
ES6 został zaakceptowany jako standard, a ES7 jest tuż za rogiem, więc zasługuje na zaktualizowaną odpowiedź. Jako przykład użyjemy ES6 + async / await z nodejs + babel, wymagania wstępne to:
Twój przykładowy foo.jsplik może wyglądać następująco:
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();
Upewnij się, że masz babel:
npm i babel-cli -g
Zainstaluj najnowsze ustawienie wstępne:
npm i babel-preset-latest
Uruchom go przez:
babel-node --presets latest foo.js
Nie wiem, dlaczego poprzednie odpowiedzi zawierały różnego rodzaju skomplikowane rozwiązania. Jeśli chcesz po prostu wykonać szybkie polecenie, takie jak ls, nie potrzebujesz async / await, callbacków ani nic. Oto wszystko, czego potrzebujesz - 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);
W celu obsługi błędów dodaj try/ catchblok wokół instrukcji.
Jeśli uruchamiasz polecenie, którego wykonanie zajmuje dużo czasu, to tak, spójrz na funkcję asynchronicznąexec .
Zależy to całkowicie od środowiska JavaScript. Proszę rozwinąć.
Na przykład podczas wykonywania skryptów systemu Windows wykonujesz następujące czynności:
var shell = WScript.CreateObject("WScript.Shell");
shell.Run("command here");
W skrócie:
// 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");
Z NodeJS jest takie proste! A jeśli chcesz uruchamiać ten skrypt przy każdym uruchomieniu serwera, możesz rzucić okiem na aplikację wiecznej usługi !
var exec = require('child_process').exec;
exec('php main.php', function (error, stdOut, stdErr) {
// do what you want!
});
Uwaga: te odpowiedzi pochodzą z klienta opartego na przeglądarce na serwer sieciowy oparty na systemie Unix.
Uruchom polecenie na kliencie
Zasadniczo nie możesz. Bezpieczeństwo mówi, że działa tylko w przeglądarce, a jej dostęp do poleceń i systemu plików jest ograniczony.
Uruchom ls na serwerze
Możesz użyć wywołania AJAX, aby pobrać dynamiczną stronę przekazującą parametry za pośrednictwem GET.
Należy pamiętać, że stwarza to również zagrożenie dla bezpieczeństwa, ponieważ musiałbyś zrobić coś, aby upewnić się, że haker pani Rouge nie spowoduje, że Twoja aplikacja powie uruchom: / dev / null && rm -rf / ......
W skrócie, ucieczka z JS to po prostu zły, zły pomysł ... YMMV
Kolejny post na ten temat z ładnym rozwiązaniem jQuery / Ajax / PHP:
Oto proste polecenie, które wykonuje ifconfigpolecenie powłoki systemu Linux
var process = require('child_process');
process.exec('ifconfig',function (err,stdout,stderr) {
if (err) {
console.log("\n"+stderr);
} else {
console.log(stdout);
}
});
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);
}
Ta funkcja może być łatwo używana, na przykład:
exec('echo test');
//output:
//test
exec('echo test', function(err, stdout){console.log(stdout+stdout+stdout)});
//output:
//testtesttest
Z nashornem możesz napisać taki skrypt:
$EXEC('find -type f');
var files = $OUT.split('\n');
files.forEach(...
...
i uruchom go:
jjs -scripting each_file.js
Jeśli używasz npm, możesz użyć pakietu shelljs
Żeby zainstalować: npm install [-g] shelljs
var shell = require('shelljs');
shell.ls('*.js').forEach(function (file) {
// do something
});
Zobacz więcej: https://www.npmjs.com/package/shelljs