Bash + Node.js + stdin/stdout重定向:错误"不是tty"

Mar*_*ein 4 stdin stdout node.js git-bash mingw-w64

此问题可能是特定于Windows的.我还没有在Linux或Mac上测试它.

我用:

  • Windows 7 64位
  • Node.js 8.1.3
  • 适用于Windows 2.8.1的Git,包括GNU bash,版本4.3.42(5) - 发行版

node my-cli.js > foo.txt:错误 output is not a tty

node my-cli.js < foo.txt:错误input is not a tty.

Mar*_*ein 6

创建一个文件my-cli:

#!/bin/sh

node "path/to/my-cli.js" "$@"
exit $?
Run Code Online (Sandbox Code Playgroud)

打电话./my-cli > foo.txt./my-cli < foo.txt.

这也适用于参数: ./my-cli --answer 42 > foo.txt


Phu*_*Ngo 5

发生这种情况是因为默认设置下的 Windows 版 Git 将提供此文件/etc/profile.d/aliases.sh,该文件将执行alias node="winpty node.exe",这是与node(以及其他程序,如python,...)交互使用所必需的。因此,当您调用时node xxx <yyy >zzz,您的外壳实际上是winpty node xxx在后台调用

winpty通过使用新的隐藏控制台窗口启动 winpty-agent.exe 进程来工作,该窗口在控制台 API 和终端输入/输出转义码之间架起桥梁。它轮询隐藏控制台的屏幕缓冲区以获取更改并生成相应的输出流。

,但副作用是标准输入和标准输出不被识别为 tty。

因此,在管道或重定向时,您可能希望调用node二进制文件本身而不是别名。有一些方法可以实现这一点:

  1. 包装在一个直接调用的 shell 脚本中,node因为非交互式 shell 不提供aliases.sh文件的来源。查看其他答案(都shbash工作)

  2. 打电话给
    env node my-cli.js > foo.txt
    command node my-cli.js > foo.txt

env在默认环境下运行命令,效果与上述方法类似;whilecommand是一个bash内置的shell,用于绕过别名。

  1. 呼叫喜欢
    \node my-cli.js > foo.txt
    'node' my-cli.js > foo.txt
    "node" my-cli.js > foo.txt

反斜杠和引号是显式绕过别名的结构。

  1. 呼叫使用
    node.exe my-cli.js > foo.txt
    /full/path/to/node my-cli.js > foo.txt
    relative/path/to/node my-cli.js > foo.txt

别名是 for node,而不是node.exenor path/to/node,它仍然指向实际的二进制文件。

扩展这些解决方案的一种方法是编写一个包装脚本来检测管道/重定向(这本身就是另一个挑战),它将决定使用winpty与否。