Question

Time for some command line fu in the least fu conducive shell, cmd.exe.

How can I perform a summation of integers contained in a file?

You might consider the following to work:

taskkill /f /im rsync.exe
echo %errorlevel% > %temp%/kill_site.log
taskkill /f /im ssh.exe
echo %errorlevel% >> %temp%/kill_site.log
taskkill /f /im 7za.exe
echo %errorlevel% >> %temp%/kill_site.log
set /a errorresult=1
for /F "tokens=*" %%G in (%temp%/kill_site.log) do set /A errorresult=%%G+%errorresult%

But, it appears that %errorresult% will always be the value before the for loop during the for loop. Meaning, the resulting %errorlevel% always has [the integer value of the last line in %temp%/kill_site.log] + [the %errorlevel% set, which is 1].

In the case of exit codes provided by taskkill, if taskkill succeeds in killing an existing process, the exit code is 0, then resulting %errorresult% in this case will be 1. If a process doesn't exist when taskkill is called to kill it, the exit code is 128; in this case the %errorresult% will be129`.

I'd like %errorresult% to be the total of all integers contained on lines in %temp%/kill_site.log. How do I do this?

[update]

Thanks to Stephen's answer below, I have a final script as follows that I wanted to include for future reference by other users:

setlocal enabledelayedexpansion
taskkill /f /im rsync.exe
echo %errorlevel% > %temp%/kill_site.log
taskkill /f /im ssh.exe
echo %errorlevel% >> %temp%/kill_site.log
taskkill /f /im 7za.exe
echo %errorlevel% >> %temp%/kill_site.log
set /a errorresult=1
for /F "tokens=*" %%G in (%temp%/kill_site.log) do set /A errorresult=%%G+!errorresult!
if %errorresult% lss 255 sendmail.vbs && eventcreate /l application /so backup_scripts /t warning /id 1 /d "website rsync has to be killed because it was long running."
endlocal

It utilizes endlocal.

I also just realized this is a bit backwards, as I should be checking if the processes are running previous to taking any invalid action against the non-existent processes, but the question is still resolved. Finding if a specific running process exists with a batch script actually uses a similar method of checking the %errorlevel% is also quite easy.

Était-ce utile?

La solution

within a forloop you need delayed expansion for your variables: use

SETLOCAL ENABLEDELAYEDEXPANSION

at the beginning of your batchfile and change your for-loop to

for /F "tokens=*" %%G in (%temp%/kill_site.log) do set /A errorresult=%%G+!errorresult!

This is because in your for-loop %errorresult% will always use the value at Parse-time. !errorresult! will use the value at run-time.

Autres conseils

Stephan's answer works fine, but there is a simpler method that doesn't require delayed expansion.

The SET /A command does its own expansion of variable names, and it always uses the current value.

set /a errorresult=1
for /F "tokens=*" %%G in (%temp%/kill_site.log) do set /A errorresult=%%G+errorresult

Or better yet

set /a errorresult=1
for /F "tokens=*" %%G in (%temp%/kill_site.log) do set /A errorresult+=%%G

Note - I don't understand why you initialize errorresult to 1. I should think 0 would make more sense.

Here is a non portable solution, but it is NOT the answer, but may assist others that come across this problem in the future:

taskkill /f /im rsync.exe
echo %errorlevel% > "%temp%/kill_site.log"
set /p res1=< "%temp%/kill_site.log"
echo > "%temp%/kill_site.log"
taskkill /f /im ssh.exe
echo %errorlevel% > "%temp%/kill_site.log"
set /p res2=< "%temp%/kill_site.log"
echo > "%temp%/kill_site.log"
taskkill /f /im 7za.exe
echo %errorlevel% > "%temp%/kill_site.log"
set /p res3=< "%temp%/kill_site.log"
echo > "%temp%/kill_site.log"
set /A errorresult=%res1% + %res2% + %res3%

I have marked this as a community wiki as the question is still pending an answer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top