当前位置: 首页 > 知识库问答 >
问题:

在运行node.js脚本时,我是否可以通过管道将输出输入到'less',而不必键入'less'?

乌翰学
2023-03-14

例如,我的脚本将使用process.stdout.write()生成大量输出。我知道我可以通过将其作为节点mycode.js | less-N运行,将它们导入less

但是有没有一种方法可以让我在代码内部执行管道,这样其他人就可以正常运行我的代码节点mycode.js,并且仍然可以通过管道将我的输出传输到less


共有3个答案

施令雪
2023-03-14

在节点内置的child\u进程的四个API中,您可能希望使用spawn,该API允许您选择在调用脚本的当前shell中运行less。所有其他选择,如execfork,都将启动一个新的不可见shell。

const spawn = require("child_process").spawn;

spawn(`cat <<< "${yourOutputString}" | less -r`, {   // <<< read the *HERE* string to cat
                                                     // less -r specifies colored output
            stdio: 'inherit', // use the current shell for stdio
            shell: true
    });

现在,只需使用节点script.js即可调用脚本。

这个冗长的教程让您全面了解child_processAPI。

何聪
2023-03-14

如果您愿意使用已编译的扩展:Node kexec,则可以从节点内部执行此操作。

我几乎精确地预制了你想要在我的项目的可执行文件中的任务,如下所示(原谅CoffeeScript):

page = (cb)->

   # If we reach this point in the code and $_PAGINATED is already set, then we've
   # successfully paginated the script and should now actually run the code meant
   # to be run *inside* a pager.
   if process.env['_PAGINATED']?
      return cb()

   # I use tricks like this to control the pager itself; they can be super-dirty,
   # though, and mutating shell-command lines without a *lot* of careful
   # invocation logic is generally a bad idea unless you have a good reason:
   pager = process.env.PAGER || 'less --chop-long-lines'
   pager = pager.replace /less(\s|$)/, 'less --RAW-CONTROL-CHARS$1'

   # I use this elsewhere in my code-base to override `term.columns` if it is
   # unset; because the pager often doesn't properly report terminal-width
   process.env['PAGINATED_COLUMNS'] = term.columns
   process.env['_PAGINATED'] = 'yes'

   # This is a horrible hack. Thanks, Stack Overflow.
   #    <https://stackoverflow.com/a/22827128>
   escapeShellArg = (cmd)-> "'" + cmd.replace(/\'/g, "'\\''") + "'"

   # This is how we *re-invoke* precisely the exact instructions that our script /
   # executable was originally given; in addition to ensuring that `process.argv`
   # is the same by doing this, `kexec` will already ensure that our replacement
   # inherits our `process.stdout` and etc.
   #
   # (These arguments are invoked *in a shell*, as in `"sh" "-c" ...`, by
   # `kexec()`!)
   params = process.argv.slice()
   params = params.map (arg)-> escapeShellArg arg
   params.push '|'
   params.push pager

   log.debug "!! Forking and exec'ing to pager: `#{pager}`"
   log.wtf "-- Invocation via `sh -c`:", params.join ' '

   kexec params.join ' '

它的调用和您预期的一样简单;类似于page(print_help_text)(这就是我使用它的方式)。

还有两个明显的缺陷:它不会神奇地将程序转移到被调用的地方,而是重新执行整个程序,直到被调用为止;因此,您需要确保在调用page()之前发生的任何事情本质上都是确定性的;i、 e.如果使用同一组命令行参数重新调用程序,则会发生完全相同的情况。(这是一种方便,不是魔术。)您可能还希望确保导致page()的代码是幂等的,即运行两次时没有任何不希望的副作用。

(如果您想在不编译本机扩展的情况下执行此操作,请尝试让Node core添加类似Ruby的exec函数。

注意:如果您决定这样做,请使用标准的-[no-]pager标志进行配置。寻呼机可以是一种很好的便利,但不是每个人都想使用它。

同样,请意识到编译依赖会给很多人带来麻烦;就我个人而言,我在我的package.jsonoptional依赖中保留了kexec,然后使用一个try/cat>(或者像可选这样的方便)来源代码。这样,如果它未能安装在用户的系统上,您的代码仍然按预期运行,只是没有寻呼机的精确。

江衡
2023-03-14

是的,您可以通过正常的child_process核心模块的API将节点程序的输出导入输入。然而,问题将是控制pty。如果您正在运行您的节点程序,它将控制pty,而less将无法访问pty,因此通过键入命令与less交互是行不通的。AFAIK(其他人可能比我更清楚)在你的节点程序中没有干净的方法来做这件事,所以我只会写一个包装器外壳脚本来做这件事,然后称之为完成。

我在npm中发现的最接近的可能性是默认寻呼机,但从我的快速测试工具来看,它似乎不起作用-(

 类似资料:
  • 问题内容: 本质上,我正在尝试替换: 为了避免使用硬盘驱动器,请在C ++中使用管道。这是我的代码: 我绝对可以确保上述字符串已正确初始化。但是,发生了两件事对我来说没有意义: (1)我正在执行的程序报告“输入文件为空”。由于我未使用“ <”调用程序,因此不应期望输入文件。相反,它应该期待键盘输入。此外,它应该阅读“ gulp_command”中包含的文本。 (2)程序的报告(通过标准输出提供)出

  • 问题内容: 我的问题与此相似:如何检测我的shell脚本是否正在通过管道运行?。区别在于我正在使用的Shell脚本是用Node.js编写的。 假设我输入: 然后,我怎么能得到的价值的? 我已经阅读了Unix和Node:管道和流,但这似乎只能提供异步解决方案(除非我误会了)。我正在寻找一个同步解决方案。同样,通过这种技术,检测脚本是否正在通过管道传输似乎不是很简单。 TL; DR我的问题有两个方面:

  • 我正在开发一个应用程序,该应用程序必须针对使用google protocol buffers 3.0.0版的目标进行交叉编译。有没有办法在protoc命令(或.proto文件)中指定生成的代码应该与protocol buffers版本3.0.0兼容,即使我用来生成代码的protoc是更高版本(如3.5.1)? 更新目标不是一个选项,我也不介意在我的开发环境中安装3.0.0,但如果说任何想要构建此代

  • 前面两节里我们用到的输入和输出都是二维数组,但真实数据的维度经常更高。例如,彩色图像在高和宽2个维度外还有RGB(红、绿、蓝)3个颜色通道。假设彩色图像的高和宽分别是$h$和$w$(像素),那么它可以表示为一个$3\times h\times w$的多维数组。我们将大小为3的这一维称为通道(channel)维。本节我们将介绍含多个输入通道或多个输出通道的卷积核。 多输入通道 当输入数据含多个通道时

  • FAQs in section [15]: [15.1] 为什么应该用 <iostream> 而不是传统的 <cstdio>? [15.2] 当键入非法字符时,为何我的程序进入死循环? [15.3] 那个古怪的while (std::cin >> foo)语法如何工作? [15.4] 为什么我的输入处理会超过文件末尾? [15.5] 为什么我的程序在第一个循环后,会忽略输入请求呢? [15.6]

  • 问题内容: 我知道通过应用boolean属性将输入元素设为只读,并且该属性不受CSS的影响。 另一方面,我的情况似乎非常适合CSS,因此我希望可以使用某种CSS技巧来实现。我的表格上有 可打印的版本 超链接。单击它会显示文档的可打印版本。它主要是CSS东西,我的print.css看起来像这样: 还有一些javascript片段,例如: 将类添加到html元素 显示没有滚动条的表 其他一些小事情,例