Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spawn is ignoring all environment variables including PATH. #12986

Closed
JemiloII opened this issue May 12, 2017 · 6 comments
Closed

Spawn is ignoring all environment variables including PATH. #12986

JemiloII opened this issue May 12, 2017 · 6 comments
Labels
child_process Issues and PRs related to the child_process subsystem. question Issues that look for answers.

Comments

@JemiloII
Copy link

Version: output of node -v
Platform: output of uname -a (UNIX), or version and 32 or 64-bit (Windows)
Subsystem: if known, please specify affected core module name

If possible, please provide code that demonstrates the problem, keeping it as
simple and free of external dependencies as you are able.
-->

  • Version: v6.9.2, v6.10.3, v7.10.0
  • Platform: Linux 3.10.0-327.13.1.el7.x86_64 deps: update openssl to 1.0.1j #1 SMP Thu Mar 31 16:04:38 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux (Centos 7)
  • Subsystem: Using nvm

So I use nvm since I have many node projects, which many have different versions. Everything has been going well until... I needed to use spawn. Node is refusing to work with spawn. It is as if node was never installed. So I tried exec, and exec can find the version of node I am using and it works as expected. Spawn on the other hand is throwing errors. It fails to include environment variables. I seriously shouldn't have to include environment variables for node. It should just use my existing ones.

console.log('version', require('child_process').execSync('node --version').toString()); works as expected

require('child_process').spawn('node', ['--version'], {stdio: 'inherit'}); fails horribly

@JemiloII
Copy link
Author

I don't like this solution, but this is how you get it working. Why does the other child_process methods have the environment variable PATH included, but spawn does not???

require('child_process').spawn('node', ['--version'], {
    cwd: process.cwd(),
    env: {
        PATH: process.env.PATH
    },
    stdio: 'inherit'
});

@JemiloII JemiloII changed the title Spawn is attempting to use a different version of node and is ignoring environment variables., Spawn is ignoring environment variables. May 12, 2017
@JemiloII JemiloII changed the title Spawn is ignoring environment variables. Spawn is ignoring all environment variables including PATH. May 12, 2017
@mscdex
Copy link
Contributor

mscdex commented May 12, 2017

Did you try adding shell: true to your spawn() options instead?

Also,

node -e 'require(`child_process`).spawn(`node`, [`-pe`, `process.env.PATH`], {stdio:`inherit`})'

prints my $PATH just fine.

@mscdex mscdex added child_process Issues and PRs related to the child_process subsystem. question Issues that look for answers. labels May 12, 2017
@JemiloII
Copy link
Author

Hmm something interesting is going on. But the behavior still doesn't seem right, however it could be intended.

require('child_process').spawn('node', ['-pe', 'process.env.PATH'], {
    cwd: process.cwd() + '/backend',
    stdio: 'inherit'
});

Prints my path as expected. however this:

require('child_process').spawn('node', ['-pe', 'process.env.PATH'], {
    cwd: process.cwd() + '/backend',
    env: {
        NODE_CONFIG_DIR: process.cwd() + '/config'
    },
    stdio: 'inherit',
    shell: true // doesn't matter if shell: true is here or not.
});

PATH is undefined...

This doesn't seem right that it would clear all the env variables when you provide an env property. If this is the case, then without having to add many environment variables to env obj, how can I just change one then?

@sam-github
Copy link
Contributor

Above is expected and documented behaviour. default value for env: is env: process.env, if you provide your own env, you chould clone process.env and add/delete any that you want to add/delete.

If you wonder why, ask yourself how you would delete a env var during spawn that you didn't want passed from the parent process to its child.

@JemiloII
Copy link
Author

JemiloII commented May 12, 2017

I think I found the answer, it wasn't obvious when I first read the docs.

From Node Core Documentation

A third argument may be used to specify additional options, with these defaults:

const defaults = {
  cwd: undefined,
  env: process.env
};

Use cwd to specify the working directory from which the process is spawned. If not given, the default is to inherit the current working directory.

Use env to specify environment variables that will be visible to the new process, the default is process.env.

Thanks for your help. Looks like all I have to do is clone process.env and then change the environment variable I want. It makes sense to why they would want spawn to work this way.

Update: @sam-github I didn't see your comment as I was posting this. Thanks :)

@joshuapinter
Copy link

Another option is to use env as the command name followed by your actual commands:

require('child_process').spawn('env', ['node', '--version'], {stdio: 'inherit'})

I found this actually worked much better than doing something like:

require('child_process').spawn('node', ['--version'], {stdio: 'inherit', env: Object.assign(process.env, {MYENV: 1})})

Found it over here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
child_process Issues and PRs related to the child_process subsystem. question Issues that look for answers.
Projects
None yet
Development

No branches or pull requests

4 participants