5

I need to create a batch file that trace out using tracert command some ip, and write the trace to txt files. I want it to be fast so I want to start for each trace a new command to make all the trace request start at once.

there is my ping.bat:

@echo off
set saveUnrechableLocation=..\pingUnreachableInfo\pingUnrechableInfoDB.txt
set IpListLocation=..\ipInfo\all_DB_ip.txt
set reachableLocation=..\pingRechableInfo\RechableIp\pingRechableInfoDB.txt
set trace=..\pingRechableInfo\tracert\tracertDB.txt
set numberOfPings=1
@echo pinging DB > %saveUnrechableLocation%
copy /y NUL %reachableLocation% > NUL
copy /y NUL %trace% > NUL
for /F "tokens=*" %%A in (%IpListLocation%) do (
    ping -n %numberOfPings% %%A | find "TTL=" >nul 
    if errorlevel %numberOfPings% (
        @echo %%A not rechable >> %saveUnrechableLocation%
    ) 
    if not errorlevel %numberOfPings% (
    @echo %%A >> %reachableLocation%
    start trace.bat %trace% %%A
    )
)

and the trace.bat look like that:

@echo off
set saveLocation=%~1
set ip=%~2
tracert %ip% >> %saveLocation%
exit

the problem is that when I'm trying to use this I'm getting this problem:

the process cannot access the file because it is being used by another process

what can I do to resolve this problem? thanks!

Moshe9362
  • 352
  • 2
  • 15

2 Answers2

5

Windows redirection does not allow multiple processes to have the same file open for write access at the same time. The write operations must be serialized. This can be done with batch processing, as demonstrated at https://stackoverflow.com/a/9344547/1012053. However, I don't think that solution will help in your case.

Each tracert process takes considerable time, and the output must be redirected the entire time. But you want multiple processes running at the same time, all output redirected to the same file. Even if you were to make it work, the output would be interleaved, and you wouldn't be able to figure out what it all means.

I recommend redirecting each tracert output to a unique file. You could incorporate the ip address into the output file name, you could use the technique I showed to merge the files after each process completes.

Note there is no need to pass the output location. Each child process has access to the trace variable, so it can easily redirect to the correct location.

outline of ping.bat changes

...
set trace=..\pingRechableInfo\tracert\tracertDB
...
start trace.bat %%A
...

modified trace.bat

@echo off
tracert %1 >%trace%_%1.txt  %= Redirect TRACERT to unique temp file =%
:merge
2>nul (  %= Hide error messages inside the outer parentheses =%
  >>%trace%.txt (  %= Attempt stdout redirection - Fails if already locked =%
    type %trace%_%1.txt  %= Write the temp file to the merge file =%
    (call )  %= Clear any error that TYPE may have generated =%
  )
) || goto :merge  %= Loop back and try again if stdout redirection failed =%
del %trace%_%1.txt  %= Delete the temporary file =%
exit

A shortened form without comments could look like:

@echo off
tracert %1 >%trace%_%1.txt
:merge
2>nul (>>%trace%.txt (type %trace%_%1.txt&(call )))||goto :merge
del %trace%_%1.txt
exit
Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • thank you very much for your answer! I didn't know that I can get to the trace var like that. just 2 simple questions: 1. by tracer you mean trace? because I didn't create a var named tracer 2. I'm kinda new to writing batch, what this line is doing? "2>nul( type %tracer%_%1.txt >>%tracer%.txt )" – Moshe9362 Apr 02 '16 at 07:50
  • 1
    @Moshe9362 - 1) Oops! Yes, I meant to write "trace" variable, not tracer. 2) See the updated answer. Note that `%= This is a comment =%`. I've fixed a syntax error bug, as well as an esoteric bug that could have lead to an endless loop if the temp file did not exist for some reason. – dbenham Apr 02 '16 at 12:08
  • actually, it's not working. It create files like `tracertDB_10.0.0.1.txt` but it didn't remove them after the process end, also it didn't copy the trace to tracertDB.txt and didn't exit the cmd-tracert commands. any suggestion? – Moshe9362 Apr 02 '16 at 15:55
  • @Moshe9362 - Ugh - Yes, the first trace.bat with comments should have worked, But the 2nd shortened form was missing a right parentheses. All fixed now. – dbenham Apr 02 '16 at 16:06
  • still, it does problems. I tried your fixing and it was no good. So I will post my fixed solution. It is similar but the batch file are really sensitive to '(' and ')' locations. I will post my fix in a new answer, just edit and post my little fix to your code and I'll remove my answer. It is your answer, but different spaces lol. thank you very much:) – Moshe9362 Apr 02 '16 at 16:12
  • @Moshe9362 - Are you sure you were looking at the most recent version of my answer? I've tested both forms of the trace.bat in my answer, and both work perfectly. – dbenham Apr 02 '16 at 18:17
  • yes I did. not working for me. I don't know why, my computer just fail to run the batch and exit in the middle – Moshe9362 Apr 02 '16 at 19:42
1

this is fixed code based on dbenham answer:

@echo off
tracert %1 >%trace%_%1.txt
:merge
2>nul (
    >>%trace%.txt ( 
        type %trace%_%1.txt
            (call )
    )
) ||goto :merge 
del %trace%_%1.txt
exit
Moshe9362
  • 352
  • 2
  • 15