119

In Bash, I can do EDITOR=vim command and command will be run with EDITOR set to vim, but this won't affect the value of EDITOR in the shell itself. Is it possible to do this in cmd.exe?

2
  • Would Powershell answers be acceptable here as well? (superuser.com/q/1049430/185554 which did not limit itself to cmd.exe was closed as a duplicate of this) Apr 20, 2021 at 10:00
  • 1
    @GertvandenBerg I certainly wouldn't object, but I don't know if moderators would (or if I should edit question title/body to extend it). Apr 20, 2021 at 11:03

5 Answers 5

82

Note that cmd /C "set "EDITOR=vim" && echo %EDITOR%" would not work.
Nor would cmd /C "setlocal ENABLEDELAYEDEXPANSION && set "EDITOR=vim" && echo !EDITOR!"

You would need:

  • the /V option, to enable delayed environment variable expansion using ! as delimiter.
  • no space between a command and the && (or add quotes)

That is:

C:\> cmd /V /C "set EDITOR=vim&& echo '!EDITOR!'"
'vim'
# or
C:\> cmd /V /C "set "EDITOR=vim" && echo '!EDITOR!'"
'vim'

As noted below by maoizm, it is cmd /V /C, not cmd /C /V (which would not work)


I can't think of any practical reason you'd ever actually want this within the context of a single command

Typically, you need this when you have to replace a value used multiple times in a long command line.
For instance, to deploy a file to Nexus (in multiple lines for readability):

cmd /v /c "set g=com.agroup&& set a=anArtifact&& set v=1.1.0&& \
           mvn deploy:deploy-file -Dfile=C:\path\!a!-!v!.jar \
           -Dpackaging=jar -DgroupId=!g! -DartifactId=!a! -Dversion=!v! \
           -DrepositoryId=nexus 
           -Durl=http://myserver/nexus/content/repositories/my-repo/"

Instead of having to replace group, artifact (used 2 times) and version in a long and complex command line, you can edit them at the beginning of said command. It is clearer/easier to manipulate and change the parameter values.

10
  • 1
    Tested it on my machine with Windows 10 version 1607, the cmd prompt crashes. Dec 21, 2016 at 20:37
  • Note that EDITOR will not be set to 'vim' but 'vim ' in the last command. Add the internal quotes to avoid the space in the end.
    – Zitrax
    Feb 3, 2017 at 11:57
  • 2
    NB: interesting: the order of switches matters in this case. cmd /v/c "..." works, but cmd /c/v "..." fails -- hopefully it can save you 15 minutes
    – maoizm
    Jun 4, 2017 at 11:12
  • 1
    @DerekGreer " I can't think of any practical reason": OK, I have edited the answer to add a practical reason.
    – VonC
    Jul 21, 2017 at 6:20
  • 3
    @DerekGreer This is also useful (and commonly used in *Nix) for apps that read environment variables. (e.g. EDITOR=emacs git commit) On windows, it could also be used to load DLLs from a custom location, by setting DEVPATH docs.microsoft.com/en-us/dotnet/framework/configure-apps/… Jan 23, 2020 at 18:32
59

You can do it in windows like this no need for installing anything.

cmd /C "set EDITOR=vim && set"

You'll see a list of variables and you'll see EDITOR=vim, now run "set" again and it won't be listed.

You can do multiple &&'s to add additional commands:

cmd /C "set EDITOR=vim && do this && do that && otherstuff"

EDIT: /C exits the new cmd right away after running, if you produce output with the new one it will still be visible in the parent window.

You can opt to use /K in which case the new cmd window stays open at the end of the run.

5
  • 9
    Be careful. Setting the variable this way will result in a trailng space in the variable EDITOR: "vim ". To avoid the trailing space use: cmd /C "set "EDITOR=vim" && do this && do that"
    – Gerd K
    Apr 3, 2015 at 12:00
  • 1
    This is not working on "Windows Server 2008", for example. I tried this: set name="username" && echo %username%. And username is empty.
    – akozin
    May 15, 2015 at 12:10
  • @akozin Do you realize that you got the keyvalue backwards? Did you mean set name=foo&&echo %name% or set username=foo&&echo %username%?
    – Phrogz
    Jul 30, 2015 at 23:00
  • @akozin see my answer below
    – VonC
    Aug 5, 2015 at 6:03
  • Your cmd = OP's command? Oct 9, 2020 at 7:47
12

you can use ported util env from package CoreUtils in GnuWin32 http://gnuwin32.sourceforge.net/

  1. Setup it
  2. Check what directory with env.exe exists in %PATH% variable
  3. Use same way like linux version env EDITOR=vim command
2
  • 2
    maybe worth saying that if you have git/docker/msys/cygwin you'll already have a version of this. Feb 26, 2018 at 16:29
  • This is specially a good choice for those who have Git Bash installed (almost every programmer these days). You can use the C:\Program Files\Git\usr\bin\env.exe executable. Jun 20, 2021 at 15:52
4

I have knocked up a batch file env.cmd which works more or less like the Linux env command:-

echo off
setlocal
for %%f in (%*) do (
  echo %%f|find "=" >nul:
  if errorlevel 1 goto DoCmd
  set %%f
  shift
)
:DoCmd
%1 %2 %3 %4 %5 %6 %7 %8 %9
endlocal

The only difference is that, because of the way cmd parses, the environment assignments need to be quoted, so your command would be:

env "EDITOR=vim" command [up to 8 parameters]

The batch file could be elaborated to remove the 8-parameter restriction by building up the command string within the for loop (delayed expansion will be needed).

2
  • Why not just use %* as the penultimate line (i.e., the one after the :DoCmd label) to allow for very long user commands? May 22, 2016 at 23:47
  • 2
    @Scott - Because %* is the original parameter list: it is unaffected by shift (unlike $* in Unix).
    – AFH
    May 23, 2016 at 0:34
4

Vonc's answer will work for commands that reference the variable as expanded (that is !FOO! instead of %FOO%)

However, It won't work if your command references a regular variable.

For example consider:

some-bat.bat (or any other executable/batch process)

echo %FOO%

And the main process:

set FOO=foo
cmd /V /C "set FOO=bar && some-bat.bat"

Returns foo instead of bar (a second execution would work though)

But still, you could concatenate a new cmd process to force the refresh of the variable.

Like this:

set "FOO=BAR" && cmd /c "echo %FOO%"

Or in case the main command already had to use a new cmd:

cmd /c "set FOO=BAR && cmd /c ^"echo %FOO%^""
1
  • 1
    Very good point. Upvoted.
    – VonC
    Apr 29, 2021 at 10:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.