Search code examples
batch-filecmdarithmetic-expressions

Perform summation of integers on each line in a file in `cmd`


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.


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.