[英]How to properly execute shell script from nodejs
I need to execute a bash script from nodejs app. 我需要从nodejs应用程序执行bash脚本。 Usually I would do something like this:
通常我会做这样的事情:
var childProcess = require('child_process');
childProcess.execFile('./test.sh', function (error, stdout, stderr) {
console.log(error, stdout, stderr);
})
But I recently ran into a bash script that never terminated when it was executed like that. 但是我最近遇到了一个bash脚本,当它那样执行时,它从未终止。 This is a minimal example that reproduces the issue:
这是重现此问题的最小示例:
#!/bin/bash
LC_CTYPE=C cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 8 | head -n 1
LC_CTYPE=C
- force the tr
to interpret everything as ascii characters LC_CTYPE=C
强制tr
将所有内容解释为ASCII字符 tr -dc "a-zA-Z0-9" < /dev/urandom
- read pseudorandom bytes, discard everything except a-zA-Z0-9
tr -dc "a-zA-Z0-9" < /dev/urandom
读取伪随机字节,丢弃除a-zA-Z0-9
以外a-zA-Z0-9
所有内容 fold -w 8
- wrap output into lines 8 characters long fold -w 8
将输出包装成8个字符长的行 head -n 1
- read the first line (8 characters) head -n 1
读取第一行(8个字符) When executed from terminal it works fine and it terminates immediately: 从终端执行时,它可以正常工作并立即终止:
# ./test.sh
0J5hsGeh
When executed using the above nodejs script it just hangs: 使用上面的nodejs脚本执行时,它会挂起:
# node test.js
It seems that the head -n 1
already terminated but the cat /dev/urandom
is still running. head -n 1
似乎已经终止,但cat /dev/urandom
仍在运行。
Question: How to execute the script from nodejs so that it does not hang? 问题: 如何从nodejs执行脚本,以使其不会挂起?
Env: 信封:
Ubuntu 16.04
Ubuntu 16.04
v6.11.2
v6.11.2
This is caused by the fact that NodeJS ignores SIGPIPE signal . 这是因为NodeJS 忽略了SIGPIPE信号 。 When a subprocess is spawned the SIGPIPE signal is ignored by the spawned subprocess as well.
生成子流程时,生成的子流程也会忽略SIGPIPE信号。
Because of that the cat
command does not terminate when the pipe is broken after the head
terminated after reading the first line. 因此,在读取第一行后终止
head
之后,当管道断开时, cat
命令不会终止。 So the cat
reads data from /dev/urandom
forever. 因此,
cat
会永远从/dev/urandom
读取数据。
It should be fixed in one of the future versions of NodeJS (not sure which though). 应该在NodeJS的未来版本之一中修复它(尽管不确定是哪一个)。 For now I just use the workaround from that issue .
现在,我仅使用该问题的解决方法。
var childProcess = require('child_process');
process.on('SIGPIPE', noop); // <----
childProcess.execFile('./test.sh', function (error, stdout, stderr) {
console.log(error, stdout, stderr);
})
process.removeListener('SIGPIPE', noop); // <----
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.