3

This works in Windows console as expected:

set A="qwerty" && echo %A%

the output: "qwerty"

But when I try to run the same commands in NPM scipts:

package.json:

"scripts": {
  "qwerty": "set A=\"qwerty\" && echo %A%"
}

> npm run qwerty

the output is: %A%

Am I doing something wrong or it just shouldn't work that way when run by NPM?

3
  • Well, your first command line does actually not work; do set "A=", then try it again, then you will get %A% echoed. To write and read a variable in the same line or block of code you need delayed expansion, so set "A=qwerty" & echo(!A! when having started the command prompt with cmd /V:ON. Alternatively, try set "A=qwerty" & call echo(%^A% (although this might still fail under some circumstances)... Commented Mar 19, 2019 at 12:07
  • Yes, my first command seemed to be working because of the previous run I guess. Commented Mar 19, 2019 at 12:15
  • Exactly, that is the reason... Commented Mar 19, 2019 at 12:17

2 Answers 2

2

Your example set A="qwerty" && echo %A% isn't correct. Variables in the cmd prompt / a batch file are expanded once per line / command:

==> set "A="

==> echo %A%
%A%

==> set A="qwerty" && echo %A%
%A%

==> echo %A%
"qwerty"

Why this behaviour?

The SET command was first introduced with MS-DOS 2.0 in March 1983, at that time memory and CPU were very limited and the expansion of variables once per line was enough.

A workaround using the CALL command:

==> set "A="

==> echo %A%
%A%

==> set A="qwerty" && CALL echo %A%
"qwerty"

Edit:

For the sake of completeness, the following batch script shows the mechanism of percent expansion and its combination with the CALL command in detail (note doubled % percent signs in the batch file CALL Echo %%_var%%):

@ECHO OFF
SETLOCAL
if NOT "%~1"=="" ECHO ON
echo        1st:
Set "_var=first"
Set "_var=second" & Echo %_var% & CALL Echo %%_var%%  
echo        2nd: 
Set "_var=first"
Set "_var=second" & CALL Echo %%_var%% & Echo %_var%  

Output, echo OFF:

==> D:\bat\SO\55237418.bat
       1st:
first
second
       2nd:
second
first

Output, echo ON:

==> D:\bat\SO\55237418.bat on

==> echo        1st:
       1st:

==> Set "_var=first"

==> Set "_var=second"   & Echo first   & CALL Echo %_var%
first
second

==> echo        2nd:
       2nd:

==> Set "_var=first"

==> Set "_var=second"   & CALL Echo %_var%   & Echo first
second
first
Sign up to request clarification or add additional context in comments.

1 Comment

I guess set A="qwerty" && echo %A% seemed to be working in my console because of the previous run which actually hadn't worked but I hadn't noticed that and saw only it working in the next runs.
2

What I found so far is that these commands in order to work properly must be in different scripts and run in a specific order. So, here is the way how it works:

"scripts": {
  "aaa": "set TMP=test && npm run bbb",
  "bbb": "echo %TMP%"
}

npm run aaa

output: test

But this one wouldn't work:

"scripts": {
  "aaa": "set TMP=test",
  "bbb": "npm run aaa && echo %TMP%"
}

npm run bbb

output: <just empty>

It looks like two separate npm run commands are required to find the created variable: the variable should be created in the first npm run and could be found in the second one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.