jmpe
jmpe

Reputation: 23

CMD Batch file: How to use a text file to input commands

I am creating a batch file to siliently install nodejs on a Windows XP machine.

I am trying to automate the installation of node module dependencies (npm install).

I would normally issue npm install from the cmd prompt in the target installation directory.

I am struggling to automate the interaction with the command prompt from a batch file.

The following line in my batch script seems to make it possible for me to pipe a text file of commands to cmd:

for /F "usebackq delims=," %%i in ("c:\foo\source\npm_install.txt") do echo %%i | "c:\windows\system32\cmd.exe"

The batch file is located in c:\foo\source. I need to issue 'npm install' from c:\foo\bin.

If my npm_install.txt file is such:

  cd /d c:\foo\bin,     
  npm install

The cmd prompt will perform the first command changing the directory from c:\ to c:\foo\bin.

It will then perform the second command but starting from c:\ again. The previous command to change directories doesn't persist. It seems every command in the text file will be issued from c:\ .

I next tried to issue both commands from a combined statment:

  cd /d c:\foo\bin && npm install

It seems this approach will allow me to overcome the prior path problem but I then have an issue with the space between npm and install.

The cmd prompt performs c:\foo\bin>npm and causes npm to trip on the space.

I have tried enclosing the command without success: 'npm install', "npm install", (npm install).

Can anyone tell me what I am doing wrong?

Thanks.

Upvotes: 1

Views: 3322

Answers (3)

James K
James K

Reputation: 4065

NOTE: These three examples do not require you to put CALL in front of any batch files, that functionality is built-into each.

The smallest and simplest, it just executes the commands with their arguments:

@echo off
for /f "tokens=*" %%x in (c:\foo\source\npm_install.txt) do (
  call %%x
)

To mimic a person typing the commands at the keyboard:

@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.
)

To end up in the same directory you started in, no matter where the script ends:

@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

Upvotes: 0

wmz
wmz

Reputation: 3685

You do not need this: do echo %%i | "c:\windows\system32\cmd.exe". Simply put your commands in a block.

do (
  command
  command
  ...
)

With your previous statement, you start new cmd interpreter, ask it to execute a command for you and exit - that's why you loose effect of that cd.

If you do not specify tokens in for loop, only 1st is read. Plus, all tokens must be on same line (I'm not sure if what you show is not a byproduct of formatting) Use "delims=" to read full line.

Do not mix commands with arguments if you do not have to: put only directories in your file:

c:\foo\bin
c:\bar\bin

so finally it becomes (I replaced cd with pushd/popd so you'll end up in the same dir you started from):

for /F "usebackq delims=" %%i in ("c:\foo\source\npm_install.txt") do (
      pushd %%i 
      npm install
      popd 
    )

Edit: if npm install is batch itself, you will need to use call, as ebohlman noted

Upvotes: 1

ebohlman
ebohlman

Reputation: 15003

The problem is that your batch-processing script is creating a new subshell to handle each line in your install file. Thus your cd command is executed in a subshell, changing its working directory, but then the subshell exits and you're back in the parent shell's working directory.

Can your main script simply call your install script (whose extension would have to be changed to ".bat")? call lets you run another batch file in the same shell and then continue running your original script.

Upvotes: 2

Related Questions