1

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.

3
  • Why would you even want to use nodejs to source a shell script?? I guess you need to export your variables out of child scope. Commented Dec 1, 2017 at 1:31
  • Limited by some project requirement. I'm curious about how. Commented Dec 1, 2017 at 1:37
  • Gave you an option, hope it helps. I would need more details about your requirement to workaround the obvious non feasibility of it. Commented Dec 1, 2017 at 6:25

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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.

1 Comment

That was my first thought too. However the sourced script may compute variables. So a basic parsing of my_var="abc" may not work great.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.