Bash + Node.js + 标准/标准输出重定向:错误"not a tty"



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

我使用:

  • 视窗 7 64 位
  • 节点.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

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

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

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

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

  1. 包装一个直接调用node的 shell 脚本,因为非交互式 shell 不会获取aliases.sh文件。查看其他答案(shbash工作)

  2. env node my-cli.js > foo.txt
    command node my-cli.js > foo.txt通话

env默认环境中运行命令,效果与上述方法类似;而command是内置的bashshell,用于绕过别名。

  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调用

别名是node的,不是node.exe也不是path/to/node,它仍然指向实际的二进制。

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

创建一个文件my-cli

#!/bin/sh
node "path/to/my-cli.js" "$@"
exit $?

拨打./my-cli > foo.txt./my-cli < foo.txt

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

由于我在 2022 年在这里在 GitBash 中遇到了同样的问题,因此其他答案之一为我指出了最简单的解决方案。

由于您已经在输入

node my-cli.js > foo.txt

您需要做的就是将node更改为node.exe,并使其他一切都保持不变。

node.exe my-cli.js > foo.txt

上面的别名答案是让我尝试这个的原因。node已设置别名,但node.exe没有别名,因此它可以按照您希望的方式工作。

sh -c 'node my-cli.js' > foo.txt对我有用

相关内容

最新更新