Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何检测Node.js脚本是否正在通过shell管道运行?_Bash_Node.js_Pipe - Fatal编程技术网

Bash 如何检测Node.js脚本是否正在通过shell管道运行?

Bash 如何检测Node.js脚本是否正在通过shell管道运行?,bash,node.js,pipe,Bash,Node.js,Pipe,我的问题与此类似:。区别在于我正在处理的shell脚本是在Node.js中编写的 假设我进入: echo "foo bar" | ./test.js 那么如何在test.js中获取值“foo bar” 我读过,但这似乎只是提供了一个异步解决方案(除非我弄错了)。我正在寻找一个同步解决方案。此外,使用这种技术,检测脚本是否正在被管道传输似乎不是很简单 TL;博士,我的问题有两个方面: 如何检测Node.js脚本是否正在通过shell管道运行,例如,echo“foo bar”|/test.js 如

我的问题与此类似:。区别在于我正在处理的shell脚本是在Node.js中编写的

假设我进入:

echo "foo bar" | ./test.js
那么如何在
test.js
中获取值
“foo bar”

我读过,但这似乎只是提供了一个异步解决方案(除非我弄错了)。我正在寻找一个同步解决方案。此外,使用这种技术,检测脚本是否正在被管道传输似乎不是很简单

TL;博士,我的问题有两个方面:

  • 如何检测Node.js脚本是否正在通过shell管道运行,例如,
    echo“foo bar”|/test.js
  • 如果是,如何读取Node.js中的管道值

  • 管道用于处理诸如“foobar”之类的小输入,但也用于处理大型文件

    streamapi确保您可以开始处理数据,而无需等待巨大的文件完全通过管道传输(这对速度和内存更有利)。它这样做的方式是通过给你大量的数据

    管道没有同步API。如果你真的想在做某件事之前把整个管道输入都拿在手里,你可以使用

    注意:仅在示例使用stream2 API时使用

    var data = '';
    function withPipe(data) {
       console.log('content was piped');
       console.log(data.trim());
    }
    function withoutPipe() {
       console.log('no content was piped');
    }
    
    var self = process.stdin;
    self.on('readable', function() {
        var chunk = this.read();
        if (chunk === null) {
            withoutPipe();
        } else {
           data += chunk;
        }
    });
    self.on('end', function() {
       withPipe(data);
    });
    
    测试

    echo "foo bar" | node test.js
    


    我刚刚找到了一个更简单的答案来回答我的部分问题

    要快速、同步地检测管道内容是否正在传递到Node.js中的当前脚本,请使用
    process.stdin.isTTY
    boolean:

    $ node -p -e 'process.stdin.isTTY'
    true
    $ echo 'foo' | node -p -e 'process.stdin.isTTY'
    undefined
    
    因此,在脚本中,您可以执行以下操作:

    if (process.stdin.isTTY) {
      // handle shell arguments
    } else {
      // handle piped content (see Jerome’s answer)
    }
    
    if (process.stdout.isTTY) {
      // not piped
    } else {
      // piped
    }
    

    我以前没有找到这一点的原因是因为我正在查看
    过程
    的文档,其中根本没有提到
    isTTY
    。相反,在中提到了它。

    如果您需要在bash中使用内联--eval字符串将管道传输到nodejs,
    cat
    也起作用:

    $ echo "Hello" | node -e "console.log(process.argv[1]+' pipe');" "$(cat)"
    # "Hello pipe"
    

    您需要检查
    stdout
    (而不是像别处建议的那样检查
    stdin
    ),如下所示:

    if (process.stdin.isTTY) {
      // handle shell arguments
    } else {
      // handle piped content (see Jerome’s answer)
    }
    
    if (process.stdout.isTTY) {
      // not piped
    } else {
      // piped
    }
    

    事实证明,
    process.stdin.isTTY
    是不可靠的,因为您可以生成一个不是TTY的子进程

    我找到了一个更好的解决方案

    您可以通过以下功能测试您的程序是否具有管道输入或输出功能:

    function pipedIn(cb) {
        fs.fstat(0, function(err, stats) {
            if (err) {
                cb(err)
            } else {
                cb(null, stats.isFIFO())
            }
        })
    }
    
    function pipedOut(cb) {
        fs.fstat(1, function(err, stats) {
            if (err) {
                cb(err)
            } else {
                cb(null, stats.isFIFO())
            }
        })
    }
    
    pipedIn((err, x) => console.log("in", x))
    pipedOut((err, x) => console.log("out", x))
    
    这里有一些测试证明它是有效的

    ❯❯❯ node pipes.js
    in false
    out false
    ❯❯❯ node pipes.js | cat -
    in false
    out true
    ❯❯❯ echo 'hello' | node pipes.js | cat -
    in true
    out true
    ❯❯❯ echo 'hello' | node pipes.js
    in true
    out false
    ❯❯❯ node -p -e "let x = require('child_process').exec(\"node pipes.js\", (err, res) => console.log(res))"
    undefined
    in false
    out false
    ❯❯❯ node -p -e "let x = require('child_process').exec(\"echo 'hello' | node pipes.js\", (err, res) => console.log(res))"
    undefined
    in true
    out false
    ❯❯❯ node -p -e "let x = require('child_process').exec(\"echo 'hello' | node pipes.js | cat -\", (err, res) => console.log(res))"
    undefined
    in true
    out true
    ❯❯❯ node -p -e "let x = require('child_process').exec(\"node pipes.js | cat -\", (err, res) => console.log(res))"
    undefined
    in false
    out true
    

    不幸的是,这将在子进程中失败:
    node-p-e“require('child\u process').exec(\“node-p-e”process.stdin.isTTY'\”,(err,res)=>console.log('err:',err,'res:',res))“
    TTY在某些情况下可能不可用(例如,在没有伪TTY的情况下启动Docker容器)并且检查
    process.stdin.isTTY
    将失败。我们能做些什么吗?对于unix程序来说似乎是一个相当简单的问题。@Lacek以什么方式失败?是
    process.stdin==未定义的
    还是什么@在节点上为我工作的maxlath14@CameronTacklind
    docker run-t--rm node node-pe'process.stdin.isTTY'
    返回
    true
    docker run--rm node-pe'process.stdin.isTTY'
    返回
    未定义的
    。因此,执行环境也会影响进程.stdin.isTTY
    。未定义的
    并不总是意味着节点进程是管道化的。这不是相反吗?i、 e.
    node foo.js | cat
    node test.js
    为我挂起在
    v10.16.0
    附带说明:如果您无法触摸原始脚本,并且仍然希望获得类似的管道测试结果,请尝试:
    /test.js$(echo'foo bar')