如何在NPM脚本中使用Windows控制台的“set”变量?

3

这在Windows控制台中按预期工作:

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

输出:"qwerty"

但是当我尝试在NPM脚本中运行相同的命令时:

package.json:

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

> npm run qwerty

输出结果为:%A%

我是否做错了什么或者这种方式在NPM下无法正常工作?

注:Original Answer翻译成“最初的回答”。

嗯,你的第一条命令行实际上是不起作用的;执行set "A=",然后再试一次,你会看到%A%被回显出来。要在同一行或代码块中写入和读取变量,你需要使用延迟扩展,所以当使用cmd /V:ON启动命令提示符时,执行set "A=qwerty" & echo(!A!。另外,你也可以尝试执行set "A=qwerty" & call echo(%^A%(虽然在某些情况下可能仍然会失败)... - undefined
是的,我猜应该是因为上一次运行的关系,我的第一个命令似乎是有效的。 - undefined
确切地说,这就是原因... - undefined
2个回答

2

你的例子 set A="qwerty" && echo %A% 是不正确的。在 cmd 提示符 / 批处理文件中,变量每行 / 命令只会扩展一次:

最初的回答

==> set "A="

==> echo %A%
%A%

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

==> echo %A%
"qwerty"

为什么会出现这种行为?

在1983年3月,MS-DOS 2.0首次引入了SET命令。那个时候,内存和CPU非常有限,每行只能扩展一次变量就足够了。

使用CALL命令的解决方法:

==> set "A="

==> echo %A%
%A%

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

编辑:

为了完整起见,以下批处理脚本详细展示了百分号扩展机制及其与 CALL 命令的组合(请注意批处理文件中的双倍 % 百分号标记: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

输出,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

1
我猜测set A="qwerty" && echo %A%在我的控制台上似乎是有效的,因为之前的运行实际上并没有成功,但我没有注意到这一点,只看到它在后续的运行中起作用。 - undefined

1
我所发现的是,这些命令为了正常运行必须在不同的脚本中,并按特定顺序运行。因此,以下是其工作方式:
"scripts": {
  "aaa": "set TMP=test && npm run bbb",
  "bbb": "echo %TMP%"
}

npm run aaa

输出: test

但这个不能工作:

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

npm run bbb

输出:<仅为空>

看起来需要使用两个独立的npm run命令才能找到创建的变量:变量应该在第一个npm run中创建,然后可以在第二个命令中找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接