简体   繁体   English

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

[英]Bash + Node.js + stdin/stdout redirection: error "not a tty"

This problem may be Windows-specific.此问题可能是特定于 Windows 的。 I have not tested it on Linux or Mac.我没有在 Linux 或 Mac 上测试过它。

I use:我用:

  • Windows 7 64 Bit视窗 7 64 位<\/li>
  • Node.js 8.1.3节点.js 8.1.3<\/li>
  • Git for Windows 2.8.1, including GNU bash, version 4.3.42(5)-release适用于 Windows 2.8.1 的 Git,包括 GNU bash,版本 4.3.42(5)-release<\/li><\/ul>

    node my-cli.js > foo.txt<\/code> : Error output is not a tty<\/code> node my-cli.js > foo.txt<\/code> : 错误output is not a tty<\/code>

    node my-cli.js < foo.txt<\/code> : Error input is not a tty<\/code> . node my-cli.js < foo.txt<\/code> :错误input is not a tty<\/code> 。

    "

Create a file my-cli :创建一个文件my-cli

#!/bin/sh

node "path/to/my-cli.js" "$@"
exit $?

Call ./my-cli > foo.txt or ./my-cli < foo.txt .调用./my-cli > foo.txt./my-cli < foo.txt

This also works with arguments: ./my-cli --answer 42 > foo.txt这也适用于参数: ./my-cli --answer 42 > foo.txt

This happens because Git for Windows on default setup will source this file /etc/profile.d/aliases.sh which will do alias node="winpty node.exe" , which is required for interactive usage with node (as well as other programs like python ,...).发生这种情况是因为默认设置下的 Windows 版 Git 将提供此文件/etc/profile.d/aliases.sh它将执行alias node="winpty node.exe" ,这是与node (以及其他程序)交互使用所必需的像python ,...)。 So when you invoke node xxx <yyy >zzz , your shell is actually calling winpty node xxx under the hood因此,当您调用node xxx <yyy >zzz ,您的外壳实际上是在winpty node xxx调用winpty node xxx

winpty works by starting the winpty-agent.exe process with a new, hidden console window, which bridges between the console API and terminal input/output escape codes. winpty工作原理是使用一个新的隐藏控制台窗口启动 winpty-agent.exe 进程,该窗口在控制台 API 和终端输入/输出转义码之间架起桥梁。 It polls the hidden console's screen buffer for changes and generates a corresponding stream of output.它轮询隐藏控制台的屏幕缓冲区以获取更改并生成相应的输出流。

, but the side effect is that the stdin and stdout is not recognised as tty's. ,但副作用是标准输入和标准输出不被识别为 tty。

So when piping or redirecting, you would want to invoke the node binary itself and not the alias.因此,在管道或重定向时,您可能希望调用node二进制文件本身而不是别名。 There are some ways to achieve this:有一些方法可以实现这一点:

  1. Wrap in a shell script which would directly call node since non-interactive shell does not source the aliases.sh file.包装在一个直接调用node的 shell 脚本中,因为非交互式 shell 不提供aliases.sh文件。 See the other answers (both sh and bash work)查看其他答案( shbash有效)

  2. Call with
    env node my-cli.js > foo.txt or env node my-cli.js > foo.txt
    command node my-cli.js > foo.txt

env runs the command in a default environment, the effect is like that of the above method; env在默认环境下运行该命令,效果与上述方法类似; while command is a bash shell built-in that is used to bypass aliases.command是一个内置的bash shell,用于绕过别名。

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

The backslash and quotation are constructs to explicitly bypass aliasing.反斜杠和引号是显式绕过别名的结构。

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

The alias is for node , not node.exe nor path/to/node , which still points to the actual binary.别名用于node ,而不是node.exepath/to/node ,它仍然指向实际的二进制文件。

A way to expand on these solutions is to write a wrapper script that detects piping / redirection (which is in itself a whole other challenge tbh) which will decide to use winpty or not.扩展这些解决方案的一种方法是编写一个包装脚本来检测管道/ 重定向(这本身就是另一个挑战 tbh),它将决定是否使用winpty

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

Since I'm here in 2022 having this same issue in GitBash, one of the other answers pointed me to the simplest solution.由于我在 2022 年来到这里,在 GitBash 中遇到了同样的问题,因此其他答案之一为我指出了最简单的解决方案。

Since you're already typing由于您已经在输入

node my-cli.js > foo.txt<\/code>

All you need to do is change node<\/code> to node.exe<\/code> and leave everything else the same.您需要做的就是将node<\/code>更改为node.exe<\/code>并保持其他所有内容不变。

node.exe my-cli.js > foo.txt<\/code>

The aliases answer above is what made me try this.上面的别名答案是让我尝试这个的原因。 node<\/code> is aliased, but node.exe<\/code> is not aliased, so it works the way you want it to work. node<\/code>有别名,但node.exe<\/code>没有别名,因此它可以按照您希望的方式工作。

"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM