Reputation: 8922
Imagine we have a env.sh
with following content.
export SOME_VAL="abcd"
We want to source this shell script from a JS (node.js) script bootstrap.js
.
const childProcess = require('child_process');
const cmd = '. ' + pathToEnvScript;
childProcess.exec(cmd, (err, stdout, stderr) => {
if (err) console.error(err);
console.log(stdout);
})
Here is how we call the bootstrap.js
.
echo $SOME_VAL # empty
node bootstrap.js
echo $SOME_VAL # empty
Why the sourcing doesn't take any effect? The sourcing works if we call source env.sh
from terminal, but doesn't work for node bootstrap.js
.
Upvotes: 1
Views: 970
Reputation: 2839
Given that
a child process cannot modify its parent env (unless you hack your shell)
the best you can do is
make nodejs tell your shell what to do to update its environment as it would have if it had sourced the script itself.
I assume you are only interested in variables and not functions.
Here is your solution.
bootstrap.js:
const childProcess = require('child_process');
const script = process.argv[2];
childProcess.exec("env > ./1.txt; . ./"+script+" >/dev/null 2>&1; env > ./2.txt; diff 1.txt 2.txt | grep '^>'", (err, stdout, stderr) => {
stdout.split('\n').forEach((line) => console.log(line.substr(2)));
})
and how you should call it:
echo $SOME_VAL # empty
eval `node bootstrap.js ./file.sh`
echo $SOME_VAL # abcd
Upvotes: 1
Reputation: 6090
this is not working for at least two reasons. source
is a Bash internal command, and node spawns /bin/sh
by default. And even if you told child_process.exec
to spawn a Bash shell:
child_process.exec("ls", { shell: "/bin/bash" }, (err, stdout) => ())
then the source
'd variables would be added to the environment of the shell process, not the environment of node.js .
I don't know what the exact specific requirements are for your project but your best bet might be to open the file in node and parse its contents to find key/value pairs and set node's environment that way.
Upvotes: 0
Reputation: 5171
childProcess.exec(command)
spawns a shell then executes the command
within that shell. Using export
makes variables available to child processes of the shell, but not to its parent. Node and the shell from which you invoke Node never see the variable.
Upvotes: 0