【问题标题】:How to execute shell command in Javascript如何在Javascript中执行shell命令
【发布时间】:2010-12-25 05:03:38
【问题描述】:

我想编写一个 JavaScript 函数来执行系统 ​​shell 命令(例如ls)并返回值。

我如何做到这一点?

【问题讨论】:

  • 您希望在客户端还是服务器上执行此命令?
  • 您使用的是哪个操作系统?
  • 这里有一个关于如何使用 node.js 作为 shell 脚本的教程:dreamsyssoft.com/javascript-shell-scripting/shell-tutorial.php
  • 为什么选择最不喜欢的答案作为最佳答案? o.0
  • 请更具体地说明什么类型的javascript。这在服务器端 javascript 上是可能的,但在客户端 javascript 上是不可能的。

标签: javascript shell command-line


【解决方案1】:

我会假设当提问者说“Shell Script”时,他的意思是 Node.js 后端 JavaScript。可能使用commander.js 来框架你的代码:)

您可以使用节点 API 中的 child_process 模块。我粘贴了下面的示例代码。

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

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 is not a function”。对 exec() 的调用执行命令 - 无需调用 child()。不幸的是,当子进程有输出时不会调用回调 - 只有当子进程退出时才会调用回调。有时可以,有时则不行。
  • 为了避免回调,可以使用execSync
  • 谁谈到了浏览器?它只说 JavaScript,仅此而已。
【解决方案2】:

我不知道为什么以前的答案给出了各种复杂的解决方案。如果你只想执行一个像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 块。

如果您运行的命令需要很长时间才能完成,那么可以,请查看asynchronous exec 函数。

【讨论】:

  • execSync 是否适用于 Mac、Linux 和 Windows 命令?
  • 已确认适用于 Windows。另外,我看到有一个shell 选项用于指定“Shell 来执行命令”。默认值:Unix 上的“/bin/sh”,Windows 上的 process.env.ComSpec。
【解决方案3】:

...几年后...

ES6 has been accepted as a standard 和 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();

确保你有 babel:

npm i babel-cli -g

安装最新的预设:

npm i babel-preset-latest

通过以下方式运行它:

babel-node --presets latest foo.js

【讨论】:

  • 如果你只需要执行一个快速命令,所有的 async/await 都是大材小用。你可以使用execSync
  • 没有人要求 Node.js 解决方案。它只说 JavaScript。
  • @Virus721: 你想在哪个 JavaScript 运行时执行 shell 命令?
【解决方案4】:

这完全取决于 JavaScript 环境。请详细说明。

例如,在 Windows 脚本中,您可以执行以下操作:

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

【讨论】:

  • 在 Linux 等类 Unix 操作系统中是否可以做同样的事情?
  • 我们如何运行这个命令:route print -4 |找到“TAP-Windows 适配器”??我试过但什么也没返回
  • 这就是我想要的。所有那些谈论他们的 Node.js 的人都很烦人。谁在这里要求 Node.js?没有人这样做。
【解决方案5】:

简而言之:

// 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");

【讨论】:

  • 对于运行在哪个网络浏览器上似乎有很多麻烦,但人们应该意识到 JavaScript 也是一种完全有效的 Windows shell 脚本语言。
  • 不熟悉那个特定的 shell "NutShell" ;)
【解决方案6】:

NodeJS 就是这么简单! 如果您想在每次启动服务器时运行此脚本,您可以查看forever-service 应用程序!

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

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

【讨论】:

  • 为了避免回调,你可以使用execSync来获得快速命令。
  • 如果想运行sudo mysql .??可能吗 ??如果是,密码是多少,这个命令后会问。
【解决方案7】:
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

【讨论】:

    【解决方案8】:

    注意:这些答案来自基于浏览器的客户端到基于 Unix 的 Web 服务器。

    在客户端运行命令

    你基本上不能。安全说只能在浏览器中运行,并且它对命令和文件系统的访问是有限的。

    在服务器上运行 ls

    您可以使用 AJAX 调用来检索通过 GET 传入参数的动态页面。

    请注意,这也会带来安全风险,因为您必须采取措施确保 mrs rouge 黑客不会让您的应用程序运行:/dev/null && rm -rf / ......

    所以简而言之,从 JS 运行只是一个坏主意...... YMMV

    【讨论】:

    • 你基本上不能以跨浏览器的方式。我相信只有 IE 有挂钩到 shell(通过 WSript/ActiveX)。
    • 所有高票答案都假设它在非浏览器上下文中运行,例如节点。正确的做法是澄清问题,而不是这个答案。
    【解决方案9】:

    这是执行 Linux 的ifconfig shell 命令的简单命令

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

    【讨论】:

    • 为了避免回调,可以使用execSync
    【解决方案10】:

    关于这个主题的另一篇文章有​​一个很好的 jQuery/Ajax/PHP 解决方案:

    shell scripting and jQuery

    【讨论】:

    • 问题指定了javascript。
    【解决方案11】:

    在 IE 中,你可以这样做:

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

    【讨论】:

    • ActiveXObject 仅适用于 IE 浏览器。
    【解决方案12】:

    如果你使用 npm,你可以使用 shelljs 包

    要安装:npm install [-g] shelljs

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

    查看更多:https://www.npmjs.com/package/shelljs

    【讨论】:

      【解决方案13】:

      使用nashorn,您可以编写如下脚本:

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

      并运行它:

      jjs -scripting each_file.js
      

      【讨论】:

        【解决方案14】:

        据我所知,官方 ECMAScript 规范中没有内置函数、方法或其他方式来运行外部进程。也就是说,允许扩展,参见规范中的this note,例如:

        注意内置函数的示例包括 parseInt 和 Math.exp。一种 主机或实现可以提供额外的内置功能, 本规范中没有描述。

        这样的“主机”之一是 Node.js,它具有 child_process 模块。让我们试试这段代码执行Linux shell命令ps -aux,保存在runps.js,基于child_process documentation

        const { spawn } = require('child_process');
        const ps = spawn('ps', ['-aux']);
        
        ps.stdout.on('data', (data) => {
          console.log(`stdout: ${data}`);
        });
        
        ps.stderr.on('data', (data) => {
          console.error(`stderr: ${data}`);
        });
        
        ps.on('close', (code) => {
          console.log(`child process exited with code ${code}`);
        });
        

        这会产生以下示例输出,在 docker 中运行它:

        $ docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app node:17-bullseye node ./runps.js
        stdout: USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
        root           1  0.0  0.8 319312 33888 ?        Ssl  11:08   0:00 node ./runps.js
        root          13  0.0  0.0   6700  2844 ?        R    11:08   0:00 ps -aux
        
        child process exited with code 0
        

        我喜欢这个模块的一点是,它包含在 Node.js 发行版中,不需要 npm install ...

        如果您在 github 中的 Node.js 代码中搜索 spawn,您将在引擎中的 C 或 C++ 中找到对 implementation 的引用。出于明显的安全原因,Firefox 和 Chrome 等现代浏览器不愿意使用这些功能扩展 JavaScript,即使 V8 等底层引擎支持它也是如此。

        请注意,最好不要以 root 身份运行我们的容器,让我们再次尝试上面的示例,这次添加 random user

        $ docker run --rm -u 7000 -v "$PWD":/usr/src/app -w /usr/src/app node:17-bullseye node ./runps.js
        stdout: USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
        7000           1  5.0  0.8 319312 33812 ?        Ssl  11:19   0:00 node ./runps.js
        7000          13  0.0  0.0   6700  2832 ?        R    11:19   0:00 ps -aux
        
        child process exited with code 0
        

        当然这样更好,但还不够。如果完全使用这种方法,则必须采取更多预防措施,例如确保不能执行任意用户命令。

        Windows 10

        我的 Windows 10 版本仍然有 Windows Script Host,它可以使用 wscript.execscript.exe 程序在控制台上运行 JScript,即不需要浏览器。要试用它,您可以打开 PowerShell Windows Terminal。将以下代码保存到可以调用shell.js的文件中:

        WScript.StdOut.WriteLine("Hallo, ECMAScript on Windows!");
        WScript.CreateObject("WScript.Shell").run("C://Windows//system32//mspaint.exe");
        

        然后在命令行上运行:

        cscript .\shell.js
        

        其中显示以下内容并打开 Paint:

        Microsoft (R) Windows Script Host Version 5.812
        Copyright (C) Microsoft Corporation. All rights reserved.
        
        Hallo, ECMAScript on Windows!
        

        存在其他变体。查找适用于您首选 JavaScript runtime environment 的文档。

        【讨论】:

          猜你喜欢
          • 2015-01-03
          • 1970-01-01
          • 1970-01-01
          • 2014-06-12
          • 2015-09-26
          • 2011-08-23
          • 1970-01-01
          • 2018-01-24
          • 2018-10-05
          相关资源
          最近更新 更多