【问题标题】:How to manipulate what `shell.which()` returns?如何操作 `shell.which()` 返回的内容?
【发布时间】:2019-07-08 17:58:34
【问题描述】:

我有一个基于 JS/Node 的 CLI,最初是为在 macOS 和 Linux 上运行而开发的。我现在想让它在 Windows 上运行,但由于复杂且固定的原因,我必须在不更改应用程序源代码的情况下实现这一目标

第一步是lie to the program about its process.platform,它工作得很好by messing with its Module(@estus 建议)并将原始 CLI 包装在另一个 CLI 中,然后在 Windows 上实际使用。

现在我偶然发现了一些运行 shelljs.which('ruby') 并将结果与​​特定字符串 (/usr/bin/ruby) 进行比较并输出错误消息甚至在不匹配时导致程序失败的代码。我还不知道如何克服。

如何操纵shell.which() 返回的内容?


可以采取的一种方法是操纵require('shelljs') 来加载我自己的shelljs 的fork,它返回我想要的任何东西(通过使用override-require,我已经用它来替换child_processcross-spawn 在 Windows 上效果更好)。但我当然想避免维护我自己的 shelljs 分支 - 如果我能以某种方式操纵 shelljs.which 会更实用。


我创建了一个与我正在使用的 CLI 类似的超小型演示项目,可用于试验可能的解决方案:https://github.com/janpio/nodejs-cli-wrongruby - fake.js 将是我想以某种方式操纵shelljs.which 的地方。

【问题讨论】:

  • 与您修改process的方式完全相同。您加载模块,用您自己的版本覆盖 which 方法,然后加载应用程序的其余部分。
  • 所以不是require('module'),而是require('shelljs'),然后直接与which混淆(如何?),后来requireshelljs不会覆盖它?我担心我似乎对这段代码理解得不够透彻。
  • require('shelljs') 被缓存并始终返回相同的模块对象,因此您可以更改它。 (如果它使用类实例,则更改内容可能会变得更加复杂)。但总的来说,你可以随便搞砸它,hereare afew examples 如何做到这一点。
  • 是的,正是我所建议的(也许除了original_which.call(this, cmd)):-) 你应该put that in an answer
  • 使用 call 确保调用原始方法时使用 shelljs 对象作为其 this 值,这可能很重要 - 但您需要查看实际实现原始which 方法满足其需求

标签: javascript node.js command-line-interface


【解决方案1】:

在 cmets 中 @Berdi 的帮助下,我发现,类似于 mess with process.platform,我也可以使用 shelljs.which 方法:

// Manipulate shelljs.which('ruby')
const shelljs = require('shelljs')
var original_which = shelljs.which
var new_which = function(cmd) {
    if(cmd == 'ruby') {
        return "/usr/bin/ruby"
    }
    return original_which.call(this, cmd)
}
shelljs.which = new_which

require("./index.js");

(假设原始 CLI 位于 ./index.js

这里所有使用参数rubyshelljs.which 的调用都以/usr/bin/ruby 应答,所有其他请求都发送到实际的shelljs.which 实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多