1
SET PORT=3000 ./node_modules/.bin/env-cmd -f .env.crkeng react-scripts start

This is the command I am attempting to run. I have node installed and this is my first time trying to use this environment. My employers think there is some problem because I am on a Windows machine, and they ususally only work with Mac. I am getting the following error:

Set-Variable : A positional parameter cannot be found that accepts argument '.env.crkeng'.

I have tried this in powershell and cmd. I only get the error in powershell, but either way nothing happens when the commend is run. I have tried enclosing different args in quotes as I've seen some people suggest on other posts, but that doesn't help.

Any ideas on how I could fix this for a Windows environment?

Compo
  • 36,585
  • 5
  • 27
  • 39
  • 2
    As an aside re the error message: In PowerShell, `SET` is - unfortunately - an alias of the [`Set-Variable`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/set-variable) cmdlet, which not only does _not_ create _environment_ variables - unlike `SET` in `cmd.exe`, whose syntax you're using - but whose syntax also differs from the latter: `PORT=3000` is interpreted as the variable _name_, `./node_modules/.bin/env-cmd` as the _value_, `-f` as the `-Force` switch, and the presence of _additional_, syntactically unexpected arguments causes the error you saw. – mklement0 Jan 07 '23 at 22:15

1 Answers1

0

It looks like you're looking for an equivalent of the following syntax commonly used in Unix (POSIX-compatible) shells such as Bash, which allows you to define an "ephemeral" environment variable that exists for a given command (child process) only:

# Unix shells such as Bash only:
# Create a command-scoped PORT environment variable with value 3000
# It is *only* defined for the child process created by the call.
PORT=3000 ./node_modules/.bin/env-cmd -f .env.crkeng react-scripts start
  • Neither cmd.exe nor PowerShell offer such a syntax, and these two shells fundamentally have very different syntax.[1]

    • This applies as of PowerShell 7.3.x, though there is a proposal to introduce support for such "ephemeral" environment variables in a future PowerShell version - see GitHub issue #3316.
  • Instead, you must define the variable first, in a separate statement and then call the target program.

    • You may also want to undefine the variable / restore its previous value afterwards.

Concrete solutions:

Note:

  • The following uses your command as specified in your question. It seems that there may be a problem with that command (possibly, npx env-cmd -f .env.crkeng react-scripts start is the correct form), which, however, is incidental to the solutions below with respect to specifying the environment variable of interest.

Without undefining / restoring afterwards (env. var. PORT will linger, with value 3000):

  • cmd.exe (note the need to use \ as the path separator):

    :: Must be *separate statements* on *separate lines*
    :: Enclosure in "..." isn't strictly needed, but a good habit to form.
    set "PORT=3000"
    .\node_modules\.bin\env-cmd -f .env.crkeng react-scripts start
    
    • If a program path contains spaces, enclose it in "..."
  • PowerShell (which accepts \ and / interchangeably):

    # *Separate statements*, either on separate lines or separated with ";"
    $env:PORT = 3000; ./node_modules/.bin/env-cmd -f .env.crkeng react-scripts start
    
    • If a program path contains spaces, enclose it in "..." (expandable string) or '...' (verbatim string) and invoke it via & (e.g., & './path with spaces/some.exe' ...)

With undefining / restoring afterwards:

  • cmd.exe: create a temporary copy of the environment with setlocal / endlocal

    setlocal
    set "PORT=3000"
    .\node_modules\.bin\env-cmd -f .env.crkeng react-scripts start
    endlocal
    
  • PowerShell: manually save and restore the previous value

    $prevPort = $env:PORT; $env:PORT = 3000
    ./node_modules/.bin/env-cmd -f .env.crkeng react-scripts start
    $env:PORT = $prevPort
    
    • Note:
      • If env. var. PORT didn't previously exist, $prevPort contains $null, and assigning $null to $env:PORT later effectively undefines (removes) it.

[1] Unfortunately, the creators of PowerShell, in a well-meaning effort to ease the transition from cmd.exe, the legacy shell, decided to create aliases named for the cmd.exe's (internal) commands as well as for some standard executables (including those on Unix-like platforms). This is why set - cmd.exe's internal command for setting (what are invariably also environment) variables - also exists as a PowerShell alias for its Set-Variable cmdlet, even though both the syntax and the purpose of these commands differ (Set-Variable only sets shell-only variables) - see the bottom section of this answer for a discussion and PowerShell-idiomatic alternatives.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thank you for your explanation! I've tried in cmd and powershell without undefining, with the methods you gave here. In cmd, when running the second command I get the following error: "'.' is not recognized as an internal or external command, operable program or batch file." If I enclose the first arg in quotes, I get an error saying "react-scripts" is not recognized. When trying in powershell with your method, I also get the "react-scripts" error – Bayley Sapara Jan 07 '23 at 18:42
  • I am still getting the following error on both powershell and cmd: "'react-scripts' is not recognized as an internal or external command, operable program or batch file. spawn react-scripts ENOENT". When I try to create default app with "npx create-react-app my-app", there are no probelms. I do not understand why react-scripts is not recognized... – Bayley Sapara Jan 07 '23 at 21:24
  • @BayleySapara, that is an unrelated problem specific to the command line you're invoking. It is `env-cmd` complaining that `react-scripts` is not the name of an executable (neither in the system's path nor in the current dir, given that `cmd.exe` is seemingly used behind the scenes). – mklement0 Jan 07 '23 at 21:27
  • @BayleySapara, in other words: This answer addresses your question _as asked_, namely how to define an environment variable on Windows that a subsequently invoked executable should see. If the call to that executable is flawed, that is a _separate problem_, which - unless there is a simple fix that a quick discussion here can resolve - should be asked _as a new question_. – mklement0 Jan 07 '23 at 21:34
  • @BayleySapara, a _potential_ quick fix would be (note the `npx` addition): `.\node_modules\.bin\env-cmd -f .env.crkeng npx react-scripts start`, or, _perhaps_: `npx env-cmd -f .env.crkeng react-scripts start` – mklement0 Jan 07 '23 at 21:35
  • 1
    Thank you for your help, these potential fixes are super helpful and I believe can be used to modify my failes for my Windows machine – Bayley Sapara Jan 07 '23 at 23:04