Welcome to the Linux Foundation Forum!

Troubles with ch-15 \ lab 1

I feel like I understand the ask, but I've honestly tried multiple runs (I'm on windows 10 BTW).

For the spawnSync, I've tried, what I feel like are, all variations where I assign options to be:

{ env: { MY_ENV_VAR: myEnvVar }}

However, every time it runs, I get every process environment variable; including the value supplied from test.ts and injected into the index method argument of myEnvVar.

I honestly don't know if this is a windows environment issue with Node, or a bad test (not accounting for how it works with windows), or I am doing it wrong. Who knows, it could even be all of them :(

Please, what am I doing wrong here?

Thanks!

P.s. I tried to be short on the answer.

Comments

  • kellv
    kellv Posts: 19

    I just tried this out on a mac and I found out it passes. This lab should be re-evaluated for windows environments.

  • Hey @kellv thanks for feeding back. All of the labs were written to work on windows, but this one is especially tricky to validate as OS's have a habit of injecting env vars into child processes. I need more info about what's going wrong, but I suspect there's an env var being injected unexpectedly by Windows - this could even be happening based on a particular way your OS is configured.

    are you using cmd or powershell?

    would you mind modifying the child.js so that on line 2 (just under 'use strict') you have:

    return console.log(process.env)

    and then run the following command:

    node -e "child_process.spawn(process.execPath, ['child.js'], {stdio: 'inherit', env: {}})"

    and paste the output here?

  • kellv
    kellv Posts: 19

    Hi David,

    Thanks for responding here.

    The local setup on window is powershell using nvs use 12
    When doing the argument injection I originally mentioned above, it is appending the property value to the already existing env vars object, which in itself is rather interesting.

    My findings were from altering the file by adding a console log for env similarly like you mentioned above as I was trying to debug my frustrations :)

    I'll go back through and do the following above with your node -e execution later. (I'm back into studying mode again).

  • kellv
    kellv Posts: 19

    @davidmarkclements I just ran your command in powershell and it I get:

    AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
    + actual - expected
    
    + undefined
    - 'is set'
        at Object.<anonymous> (C:\Users\kelly\jsnad\Labs-2020-06-07\ch-15\labs-1\child.js:9:8)
        at Module._compile (internal/modules/cjs/loader.js:1138:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
        at Module.load (internal/modules/cjs/loader.js:986:32)
        at Function.Module._load (internal/modules/cjs/loader.js:879:14)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
        at internal/main/run_main_module.js:17:47 {
      generatedMessage: true,
      code: 'ERR_ASSERTION',
      actual: undefined,
      expected: 'is set',
      operator: 'strictEqual'
    }
    

    So. it looks like that works as expected

  • hey @kellv can you make sure to modify child.js so line two is exactly:

    return console.log(process.env)

    and then run the command

    I want to exit early (return) and log out the env

  • kellv
    kellv Posts: 19
    edited September 2020

    As you officially requested sir. (and again, thank you) :)

    {
      HOMEDRIVE: 'C:',
      HOMEPATH: '\\Users\\kelly',
      LOGONSERVER: '\\\\DESKTOP-XXXXXX',
      PATH: 'C:\\Users\\kelly\\AppData\\Local\\nvs\\node\\12.18.0\\x64;C:\\Python38\\Scripts\\;C:\\Python38\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\
    \System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\ProgramData\\chocolatey\\bin;C:\\Program Files\\dotnet\\;C:\\Program Files\\Git\\cmd;C:\\Users\\kelly\\App
    Data\\Local\\Microsoft\\WindowsApps;C:\\Users\\kelly\\AppData\\Local\\Programs\\Microsoft VS Code\\bin;C:\\Users\\kelly\\AppData\\Local\\JetBrains;C:\\Users\\kelly\\AppData\\Local\
    \nvs\\',
      SYSTEMDRIVE: 'C:',
      SYSTEMROOT: 'C:\\WINDOWS',
      TEMP: 'C:\\Users\\kelly\\AppData\\Local\\Temp',
      USERDOMAIN: 'DESKTOP-XXXXXX',
      USERNAME: 'kelly',
      USERPROFILE: 'C:\\Users\\kelly',
      WINDIR: 'C:\\WINDOWS'
    }
    

    And to add, I get the same results running in powershell and cmd

  • Hey, got the same thing. Works on mac , not on windows. Error received: "child process should only have one env var".

  • hey @kellv to get that output did you run

    node -e "child_process.spawn(process.execPath, ['child.js'], {stdio: 'inherit', env: {}})"

    or

    node child.js

  • Hello @davidmarkclements,

    I'm struggling to get it on Windows too, BTW I edited child.js

    'use strict'
    const assert = require('assert')
    const clean = (env) => Object.fromEntries(
      Object.entries(env).filter(([k]) => !/^(_.*|pwd|shlvl)/i.test(k))
    )
    const env = clean(process.env)
    
    console.log(env)
    
    assert.strictEqual(env.MY_ENV_VAR, 'is set')
    assert.strictEqual(
      Object.keys(env).length,
      1,
      'child process should have only one env var'
    )
    console.log('passed!')
    

    Adding the console.log(env) tried running it via the command

    MINGW64 ~/Desktop/applications/certification/labs/ch-15/labs-1
    $ node -e "child_process.spawn(process.execPath, ['child.js'], {stdio: 'inherit', env: { MY_ENV_VAR: 'is set' }})"
    {
      HOMEDRIVE: 'C:',
      HOMEPATH: '\\Users\\elaconico',
      LOGONSERVER: '...',
      MY_ENV_VAR: 'is set',
      PATH: 'C:\\Program Files\\Git\\mingw64\\bin;C:\\Program Files\\Git\\usr\\bin;C:\\Users\\elaconico\\bin;C:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath;C:\\Python27\\;C:\\Python27\\Scripts;C:\\ProgramData\\DockerDesktop\\version-bin;C:\\Program Files\\Docker\\Docker\\Resources\\bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\Microsoft VS Code\\bin;C:\\Program Files\\PuTTY\\;C:\\xampp\\php;C:\\composer;C:\\Program Files\\TortoiseSVN\\bin;C:\\Program Files\\Redis\\;C:\\Users\\elaconico\\AppData\\Roaming\\nvm;C:\\nodejs;C:\\Program Files (x86)\\GnuWin32\\bin;C:\\Program Files\\Git\\cmd;C:\\Program Files\\heroku\\bin;C:\\Ruby26-x64\\bin;C:\\Users\\elaconico\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files\\OpenVPN\\bin;C:\\Users\\elaconico\\AppData\\Roaming\\Composer\\vendor\\bin;C:\\Program Files\\MongoDB\\Server\\4.2\\bin;C:\\ffmpeg\\bin;C:\\Program Files\\WhoLockMe',
      SYSTEMDRIVE: 'C:',
      SYSTEMROOT: 'C:\\WINDOWS',
      TEMP: 'C:\\Users\\ELACON~1\\AppData\\Local\\Temp',
      USERDOMAIN: '...',
      USERNAME: 'elaconico',
      USERPROFILE: 'C:\\Users\\elaconico',
      WINDIR: 'C:\\WINDOWS'
    }
    assert.js:118
      throw new AssertionError(obj);
      ^
    
    AssertionError [ERR_ASSERTION]: child process should have only one env var
        at Object.<anonymous> (C:\Users\elaconico\Desktop\applications\certification\labs\ch-15\labs-1\child.js:11:8)
        at Module._compile (internal/modules/cjs/loader.js:1085:14)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        at Module.load (internal/modules/cjs/loader.js:950:32)
        at Function.Module._load (internal/modules/cjs/loader.js:790:14)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
        at internal/main/run_main_module.js:17:47 {
      generatedMessage: false,
      code: 'ERR_ASSERTION',
      actual: 12,
      expected: 1,
      operator: 'strictEqual'
    }
    

    blurred some of the value with ...
    and yes, it seems it is injecting unwanted env vars, should we modify this then? Object.entries(env).filter(([k]) => !/^(_.*|pwd|shlvl)/i.test(k))

    Thank you for your support!

  • UPDATE

    It seems to be a regex issue,
    I tried modifying the clean function

    FROM

    const clean = (env) => Object.fromEntries(
      Object.entries(env).filter(([k]) => !/^(_.*|pwd|shlvl)/i.test(k))
    )
    

    TO

    const clean = (env) => Object.fromEntries(
      Object.entries(env).filter(([k]) => /^(MY_ENV_VAR)/i.test(k))
    )
    

    OUTPUT

    MINGW64 ~/Desktop/applications/certification/labs/ch-15/labs-1
    $ node -e "child_process.spawn(process.execPath, ['child.js'], {stdio: 'inherit', env: { MY_ENV_VAR: 'is set' }})"
    { MY_ENV_VAR: 'is set' }
    passed!
    

    tried intentionally to make it not work

    const clean = (env) => Object.fromEntries(
      Object.entries(env).filter(([k]) => /^(MY_ERROR_VAR)/i.test(k))
    )
    

    OUTPUT

    MINGW64 ~/Desktop/applications/certification/labs/ch-15/labs-1
    $ node -e "child_process.spawn(process.execPath, ['child.js'], {stdio: 'inherit', env: { MY_ENV_VAR: 'is set' }})"
    {}
    assert.js:118
      throw new AssertionError(obj);
      ^
    
    AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
    + actual - expected
    
    + undefined
    - 'is set'
        at Object.<anonymous> (C:\Users\elaconico\Desktop\applications\certification\labs\ch-15\labs-1\child.js:10:8)
        at Module._compile (internal/modules/cjs/loader.js:1085:14)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        at Module.load (internal/modules/cjs/loader.js:950:32)
        at Function.Module._load (internal/modules/cjs/loader.js:790:14)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
        at internal/main/run_main_module.js:17:47 {
      generatedMessage: true,
      code: 'ERR_ASSERTION',
      actual: undefined,
      expected: 'is set',
      operator: 'strictEqual'
    }
    

    Hope this helps.

  • I had the same issue, switched to Ubuntu WSL to pass

  • @elaconico - unfortunately your changes just lead to asserting that true is true, we don't just want MY_ENV_VAR to be set, we want it to to be the ONLY env var that is set

    if you could console log env in the clean function and post results here I can take a look at seeing what else is in the way here

  • theodoros
    theodoros Posts: 17
    edited December 2021

    I almost managed to ovewrite the environment variables but on the assertion i get another one variable, apart from the one that we need.

    I create an options object, where i add the env variable that we need:

    excersice(myEnvVar){
        const exec_options = {
           cwd: null, 
           env: { MY_ENV_VAR: myEnvVar },
           encoding: 'utf8',
           timeout: 0,
           maxBuffer: 200 * 1024
        }
    
      const childprocess = spawn(process.execPath, ['-p', 'process.env'], exec_options)
      return childprocess
      }
    

    But the output that i get on the node test has one more env variable. Can someone give me a clue why this __CF_USER_TEXT_ENCODING: is added on its own ?

  • all good now, i added the {stdio: inherit} on the exec_options, and added the child.js, and all worked.

     const exec_options = {
        env: { MY_ENV_VAR: myEnvVar },
        stdio: 'inherit'
     }
    
     const childprocess = spawn(process.execPath, ['child.js'], exec_options)
    
  • krave
    krave Posts: 45

    I run all labs code based on Docker without issues and my host machine is Windows too.

  • @krave that makes sense because Docker is generally linux, so really you're running the code on linux.

  • krave
    krave Posts: 45

    Aha, really love to write code based on docker now. :smile: Thanks to WSL2 and VScode remote extensions. <3

  • nice :+1:

  • doruk
    doruk Posts: 5

    Since child process inherits parent process.env by default, I just did process.env = { ... } before spawn().

  • @doruk what we're trying to demonstrate here is that the env option passed to spawn creates a clean env. On Windows, that's not entirely true (but it mostly is). So while your approach will cause you to pass the item, it's obviously not a good idea to clear all of process env in the parent process in real-world scenarios.

Categories

Upcoming Training