通过Node.js子进程区分bash和sh

时间:2016-12-09 19:53:57

标签: node.js linux bash shell

我使用bashsh使用Node.js启动子进程,如下所示:

const file = '<some-path>.sh';  
const cp = require('child_process');

//sh
const n = cp.spawn('sh',[file]);

//bash
const n = cp.spawn('bash',[file]);

我遇到的问题是,文件系统上经常有.sh个文件,实际上只能由bash 解释。

即使说.sh文件有以下hashbang

#!/usr/bin/env bash

如果我使用sh明确启动该流程,则脚本将使用sh而不是bash执行,然后sh会引发错误。

例如,read -u命令是bash实用程序,而不是sh。

通常使用hashbang并运行如下脚本来解决问题:

./<some-path>.sh

然而,在Node.js中,我必须选择是使用sh还是bash,我不会事先知道它是什么类型的脚本!

我应该为sh文件强制执行.sh的文件扩展名约定,为bash脚本执行.bash吗?

或者Node.js是否有办法启动“低级内核进程”而不是sh或bash来评估shell脚本以确定是使用bash还是sh?

1 个答案:

答案 0 :(得分:1)

经过一些研究,我认为exec命令是我要找的那个:

https://linux.die.net/man/3/exec

但是当我这样使用它时,我收到了一个错误。

 const n = cp.spawn('exec', ['file.sh']);

错误如下:

 Error: spawn exec ENOENT
    at exports._errnoException (util.js:1022:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32)
    at onErrorNT (internal/child_process.js:359:16)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickDomainCallback (internal/process/next_tick.js:122:9) 

错误源自此处:

n.on('error', function (err) {
      console.error('\n',err.stack || err,'\n');   // here
    });

然而,这似乎有效!

首先,使用以下命令确保shell脚本可执行:

chmod u+x <file.sh>

然后我们可以这样执行:

const n = cp.spawn('/absolute/path/to/file.sh');

这将调用由hashbang确定的正确解释器,例如:

#!/usr/bin/env bash

瞧!