0

How can I keep the command window from closing after running my batch script. I want to keep it open for troubleshooting and testing purposes. It closes after I put in the ping and if errorlevel part in. Is my code correct and how can I keep it from closing?

@echo on

for /f %%a in (pclist.txt)  do ( 

ping -n 1 \\%%a > NUL
IF ERRORLEVEL 0 (goto :copyhost1) ELSE goto :skipcopyhost1

:copyhost1

ROBOCOPY "\\%%a\C$\folder" "\\servername\folder" /MOVE

ROBOCOPY "\\%%a\C$\folder2" "\\servername\folder2" /MOVE

ROBOCOPY "\\%%a\C$\folder3" "\\servername\folder3" /MOVE

:skipcopyhost1

)

PAUSE

Here is what I know does work:

@echo on

for /f %%a in (pclist.txt)  do ( 
ROBOCOPY "\\%%a\C$\folder" "\\servername\folder" /MOVE

ROBOCOPY "\\%%a\C$\folder2" "\\servername\folder2" /MOVE

ROBOCOPY "\\%%a\C$\folder3" "\\servername\folder3" /MOVE

)

PAUSE
arealhobo
  • 447
  • 1
  • 6
  • 17

3 Answers3

2

Probably the source of all your problems are the labels and the goto commands.

  • You should not define labels inside blocks of code (code enclosed in parenthesis). Usually these labels lead to parse errors.

  • Inside for loops the usage of a goto command cancels the for and no more values are iterated.

Also there are problems with your usage of the if errorlevel n construct. This condition is evaluated to true for any errorlevel value greater than or equal to n. That makes your condition to be evaluated to true for all errorlevel values except negative ones.

The ping command is also a source of problems (for more information read here). The usual way to check if the machine is online is to test for presence of the TTL= string in the output with the find command. If the string is found (errorlevel = 0) the ping was sucessful, if it is not found (errorlevel = 1) the machine is offline.

@echo on
    setlocal enableextensions disabledelayedexpansion

    for /f %%a in (pclist.txt)  do ( 
        ping -n 1 %%a | find "TTL=" > nul 
        if not errorlevel 1 (
            ROBOCOPY "\\%%a\C$\folder" "\\servername\folder" /MOVE
            ROBOCOPY "\\%%a\C$\folder2" "\\servername\folder2" /MOVE
            ROBOCOPY "\\%%a\C$\folder3" "\\servername\folder3" /MOVE
        )
    )
    pause
Community
  • 1
  • 1
MC ND
  • 69,615
  • 8
  • 84
  • 126
1

First off, I'm pretty much a novice at batch scripting, but I'll point out a couple of things I noticed with your original code.


@echo on <- Isn't needed as echo is enabled by default, this will only tell you that echo is enabled.

for /f %%a in (pclist.txt)  do ( <- I imagine that pclist.txt has a list of IP's, fine and dandy, we'll work with that.

ping -n 1 \\%%a > NUL <- The \\ isn't needed >NUL isn't required for my corrected proposed solution.
IF ERRORLEVEL 0 THEN goto :copyhost1 ELSE goto :skipcopyhost1 <- Ping, not really setup to handle ERRORLEVEL.

Hint for the future, IF %ERRORLEVEL%==0 GOTO blah

:skipcopyhost1 <- Next couple lines, shouldn't be in the loop
echo test
:copyhost1
echo test1

) <- Should be moved up a few lines

PAUSE

Now, this solution would work, even if your pclist.txt has mixed active/ nonactive hosts, this will continue until the end of the file has been reached. As I mentioned, PING, isn't really setup to handle ERRORLEVELs, so we'll pipe the command to FINDSTR to search for text only found in an active host, this will also suppress the ping dialog. Once a host has been found, sets the ip to %Host%, which is how you'll have to refer to it for the robocopy. I didn't mess with the robocopy command besides to get rid of the %%a. Anyways, hope this is what you were looking for.

@ECHO OFF

FOR /F %%a in (pclist.txt)  DO (
CLS
TITLE Pinging %%a
PING -n 1 %%a | FINDSTR TTL && SET Host=%%a && CALL :CopyHost
)
EXIT

:CopyHost
TITLE Copying files to: %Host%
ROBOCOPY "\\%Host%\C$\folder" "\\servername\folder" /MOVE
ROBOCOPY "\\%Host%\C$\folder2" "\\servername\folder2" /MOVE
ROBOCOPY "\\%Host%\C$\folder3" "\\servername\folder3" /MOVE
GOTO :EOF
Potato Head
  • 143
  • 1
  • 8
  • This does not appear to be working, it is attempting to robocopy from \\%a and not from the actual list of computer names. – arealhobo Oct 20 '15 at 20:43
  • Like I said, I didn't mess with the `robocopy` at all. except swapping out the `%%a` to `%Host%`. My biggest concern was to get the batch file to correctly ping a list of hosts from the text file. %%a shouldn't have anything to do with the robocopy, that's why %host% is set. – Potato Head Oct 20 '15 at 21:35
  • Shouldn't the robocopy still be inside do ()? I am pretty much a beginner at scripting so I wouldn't really know! – arealhobo Oct 20 '15 at 23:37
  • It's not necessary, because than you'll be trying to `robocopy` irregardless if an active host is found or not. although looking at that little bit I did write, there should be an `exit`, or whatever piece of code you'd want to run after the loop runs, right after the loop, before the `:CopyHost` just to avoid accidentally running `robocopy` when the loop finishes. – Potato Head Oct 21 '15 at 02:33
0

Are you sure robocopy is not failing?

Try just this:

@echo on

for /f %%a in (pclist.txt)  do ( 

ping -n 1 \\%%a > NUL
IF ERRORLEVEL 0 THEN goto :copyhost1 ELSE goto :skipcopyhost1

:skipcopyhost1
echo test
:copyhost1
echo test1

)

PAUSE

Does it pause? If yes, add first robocopy command, save the file and run again. If it succeeds, add the next one and so on. The above batch commands work fine on Windows 10 32-bit and my hope is that it will work for you as well.

zedfoxus
  • 35,121
  • 5
  • 64
  • 63