我正在创建一个批处理文件,以便在Windows XP计算机上轻松安装nodej。
我正在尝试自动安装节点模块依赖项(npm install)。
我通常会从目标安装目录中的cmd提示符发出npm install。
我正在努力通过批处理文件自动执行与命令提示符的交互。
我的批处理脚本中的以下行似乎可以将命令的文本文件传递给cmd:
for /F "usebackq delims=," %%i in ("c:\foo\source\npm_install.txt") do echo %%i | "c:\windows\system32\cmd.exe"
批处理文件位于c:\ foo \ source中。我需要从c:\ foo \ bin发出'npm install'。
如果我的npm_install.txt文件是这样的:
cd /d c:\foo\bin,
npm install
cmd提示符将执行第一个命令,将目录从c:\更改为c:\ foo \ bin。
然后它将执行第二个命令,但是再次从c:\开始。上一个更改目录的命令不会保留。似乎文本文件中的每个命令都将从c:\。
发出我接下来尝试从合并的语句中发出两个命令:
cd /d c:\foo\bin && npm install
似乎这种方法可以让我克服先前的路径问题,但是我遇到了npm和install之间的空间问题。
cmd提示执行c:\ foo \ bin> npm并导致npm在空格上跳闸。
我试过封闭命令但没有成功:'npm install',“npm install”,(npm install)。
谁能告诉我我做错了什么?
感谢。
答案 0 :(得分:2)
问题是您的批处理脚本正在创建一个新的子shell来处理安装文件中的每一行。因此,您的cd
命令在子shell中执行,更改其工作目录,但随后子shell退出,您将回到父shell的工作目录中。
您的主脚本可以只是call
您的安装脚本(其扩展名必须更改为“.bat”)吗? call
允许您在同一个shell中运行另一个批处理文件,然后继续运行原始脚本。
答案 1 :(得分:1)
你不需要这个:
do echo %%i | "c:\windows\system32\cmd.exe"
。只需将命令放在一个块中即可。
do (
command
command
...
)
使用您之前的语句,您启动新的cmd解释器,让它为您执行命令并退出 - 这就是您放松cd
的效果的原因。
如果未在for循环中指定标记,则只读取第1个标记。此外,所有令牌必须在同一行(我不确定您显示的内容是否不是格式化的副产品)
使用"delims="
读取完整行。
如果您不需要,请不要将命令与参数混合:只在文件中放置目录:
C:\ FOO \ BIN
c:\ bar \ bin
所以最后它变成了(我用pushd / popd替换了cd,所以你最终会在你开始的同一个目录中):
for /F "usebackq delims=" %%i in ("c:\foo\source\npm_install.txt") do (
pushd %%i
npm install
popd
)
修改:如果npm install
本身是批处理,则需要使用通话,因为 ebohlman 注明
答案 2 :(得分:0)
注意:这三个示例 not 要求您将CALL
放在任何批处理文件的前面,这些功能都内置于每个文件中。
最小也是最简单的,只需执行命令 :
@echo off
for /f "tokens=*" %%x in (c:\foo\source\npm_install.txt) do (
call %%x
)
模仿在键盘上输入命令的人:
@echo off
for /f "tokens=*" %%x in (c:\foo\source\npm_install.txt) do (
setlocal enabledelayedexpansion
:: Mimic commandline
call set "cmd=%%cd%%"
echo !cmd!^>%%x
endlocal
:: Preform command
call %%x
echo.
)
无论脚本在何处结束,最终都会在您开始的同一目录中结束:
@echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%x in (c:\foo\source\npm_install.txt) do (
:: Mimic commandline
call set "cmd=%%cd%%"
echo !cmd!^>%%x
:: Preform command
call %%x
echo.
)
endlocal