【问题标题】:CMD Batch file: How to use a text file to input commandsCMD 批处理文件:如何使用文本文件输入命令
【发布时间】:2012-09-08 14:01:56
【问题描述】:

我正在创建一个批处理文件以在 Windows XP 机器上静默安装 nodejs。

我正在尝试自动安装节点模块依赖项 (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)。

谁能告诉我我做错了什么?

谢谢。

【问题讨论】:

    标签: node.js batch-file windows-xp cmd


    【解决方案1】:

    问题在于您的批处理脚本正在创建一个新的子shell 来处理安装文件中的每一行。因此,您的cd 命令在子shell 中执行,更改其工作目录,但随后子shell 退出,您又回到父shell 的工作目录。

    您的主脚本可以简单地call您的安装脚本(其扩展名必须更改为“.bat”)吗? call 允许您在同一个 shell 中运行另一个批处理文件,然后继续运行您的原始脚本。

    【讨论】:

    • 感谢您帮助我理解 subshel​​l。
    【解决方案2】:

    你不需要这个: do echo %%i | "c:\windows\system32\cmd.exe"。只需将您的命令放在一个块中。

    do (
      command
      command
      ...
    )
    

    使用您之前的语句,您启动新的 cmd 解释器,要求它为您执行命令并退出 - 这就是您失去 cd 效果的原因。

    如果你没有在 for 循环中指定标记,则只读取第一个。另外,所有标记必须在同一行(我不确定您显示的内容是否不是格式化的副产品) 使用"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 所述

    【讨论】:

    • 使用“tokens=*”读取整行。 "tokens=" 可能有效,但也可能有意想不到的副作用。 for /? 解释如何使用for
    • @wmz 一种有趣的方式来做相当于“tokens=*”的事情。我从来没想过。
    【解决方案3】:

    注意:这三个示例要求您将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
    

    【讨论】:

    • 为了在完成后获得最小的让您回到原始目录,请将代码包装在 setlocalendlocal 之间。 (enableDelayedExpansion 不是必需的。)
    猜你喜欢
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2022-01-05
    • 2016-01-31
    • 2013-11-21
    • 1970-01-01
    相关资源
    最近更新 更多