0

I have following batch script but instead of variable value I get "ECHO is on." printed. Could you please help? I don't know if this has any impact but just to note, test.bat gives current CPU temperature, for ex. 3200

SET RESULT
FOR /F %%a in ('test.bat') do SET RESULT=%%a
ECHO %RESULT%

EDIT: Now I understood that result variable is empty but didn't understand why? I have executed following command separately and it returns temperature: wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature

missx
  • 47
  • 7
  • 3
    The point is that if `RESULT` is empty, then `ECHO %RESULT%` expands to `ECHO`, and `ECHO` with no parameters outputs the echo status. – Nate Eldredge Dec 17 '20 at 18:29
  • @NateEldredge Oh okay, now I understood, thank you. But then why my result variable is empty? I have executed following command separately and it returns temperature: ```wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature``` – missx Dec 17 '20 at 18:32
  • 1
    Check output from `set RESULT` along with `ECHO %RESULT%`. Maybe the `RESULT` variable _contains_ the `ECHO is on.` string returned by `test.bat`? – JosefZ Dec 17 '20 at 18:33
  • @JosefZ test.bat returns cpu temperature for ex 3200 but I don't know why this value is not being assigned to result variable. test.bat contains: ```wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature``` and this command works for me seperately – missx Dec 17 '20 at 18:47
  • 3
    See [Dave Benham's *`WMIC` and `FOR /F`: A fix for the trailing `` problem*](http://www.dostips.com/forum/viewtopic.php?f=3&t=4266). – JosefZ Dec 17 '20 at 18:56
  • 2
    `FOR /F %%a in ('test.bat') do for /F %%A in ("%%a") do SET RESULT=%%A` should do the trick… – JosefZ Dec 17 '20 at 19:19
  • @JosefZ Thank you for link and solution. This solution gave me different output similar to my comment on Stephan's answer(I couldn't post here because of character restriction). I think better if I continue this time with separate file and then read further about this topic. – missx Dec 17 '20 at 19:59
  • I'd be interested to know what makes you believe that the figure given in tenths of a degree Kelvin is the CPU temperature, and not simply the temperature in one thermal zone! I also believe that the temperture reported is not the currently one, but that taken when last polled. – Compo Dec 17 '20 at 22:29
  • @Compo Hmm, actually I never thought it can be other thermal zone, thanks for mentioning and yes, it is the last polled, I've created job to run command each minute, it's always around 45-49 Celsius, I would like to believe it's CPU :D – missx Dec 17 '20 at 23:00
  • The point I was trying to make is that you will not know when it was polled, your command isn't polling it. You should with sufficient results be able to see some changes, but in my opinion they will mean absolutely nothing, especially when most processors will handle double what you're reporting. The majority of PC's do not support that WMI query, the figures aren't accurate or up to date, there's no guarantee what zone the temperature it is reported and most systems should already have some triggers built-in for exceeding certain temperatures. Is it really worth it? – Compo Dec 17 '20 at 23:12

2 Answers2

2

Your problem here isn't primarily the ugly wmic line ending of CRCRLF, but an empty line at the end (which for doesn't recognize as empty, because it contains a superfluous CR). Just filter the output of test.bat for non-empty lines. As a bonus, the piping to findstr also gives you a proper Windows line ending.

FOR /F %%a in ('test.bat^|findstr "."') do SET RESULT=%%a
ECHO %RESULT%

Note: with this method you get the last line only (previously the empty line, now the last non-empty line). The wmic command you use, gives me two temperatures (where only the last one is kept by the variable) on my system. you might want to consider that.

Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Thank you for the warning and solution This solution gives me odd output below. I think better to continue this time with separate file and then to read more about ```CR LF findstr``` ```C:\Users\User\Documents>myScriptCPUtemp.bat C:\Users\User\Documents>FOR /F %a in ('test.bat|findstr "."') do SET RESULT=%a C:\Users\User\Documents>SET RESULT=C:\Users\User\Documents>wmic C:\Users\User\Documents>SET RESULT=CurrentTemperature C:\Users\User\Documents>SET RESULT=3232 C:\Users\User\Documents>ECHO 3232 3232 ``` – missx Dec 17 '20 at 19:45
  • 2
    You obviously have no `@echo off` in your `test.bat`. What you see is the command repetition. Add `@echo off` as first line to both scripts. Btw: you can also use`FOR /F %%a in ('wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature^|findstr "."') do ...`. No need for two scripts. – Stephan Dec 17 '20 at 20:05
  • Yes, you are right, thank you for the explanation, that repetition was because I didn't write ```echo off``` – missx Dec 17 '20 at 20:10
1

Here's what I would do:

The problem is that the output for:

wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature

...results in an blank line at the end, which overrides the set command with the actual temperature. To work around this, the output is directed to file, and then used to set the value. even though the output file contains the blank line, SET will only read the first line of any file.

Console

IF EXIST "var_$CPU_TEMPERATURE.txt" del /q "var_$CPU_TEMPERATURE.txt"
for /F "skip=1 tokens=1 delims=" %P IN ('wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature') DO (echo %P>> var_$CPU_TEMPERATURE.txt) && (SET /P $CPU_TEMPERATURE= <var_$CPU_TEMPERATURE.txt)
echo %$CPU_TEMPERATURE%

Script

IF EXIST "var_$CPU_TEMPERATURE.txt" del /q "var_$CPU_TEMPERATURE.txt"
for /F "skip=1 tokens=1 delims=" %%P IN ('wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature') DO (echo %%P>> var_$CPU_TEMPERATURE.txt) && (SET /P $CPU_TEMPERATURE= <var_$CPU_TEMPERATURE.txt)
%echo $CPU_TEMPERATURE%
  • it's possible to do it without the need for a (temporary) file. – Stephan Dec 17 '20 at 19:31
  • @Stephan Can you give an example that uses a for loop to get a value and sets that value to a variable. The condition is that the value being returned includes an empty line, so that the for loop uses last line to set the variable to an empty string. Good example would be to use: FOR /F "tokens=2 delims==" %P IN ('wmic timezone get StandardName /value') DO SET $UTC_NAME=%P – David Geeraerts Dec 17 '20 at 23:18
  • I described this method (well to be exact, one of several methods) in [my answer](https://stackoverflow.com/a/65347151/2152082). Besides - your code works fine for me (except that `wmic` line ending - see the [link](http://www.dostips.com/forum/viewtopic.php?f=3&t=4266), JosefZ linked yesterday for methods to overcome that) – Stephan Dec 18 '20 at 08:41
  • @Stephan Thank you for posting the [link](http://www.dostips.com/forum/viewtopic.php?f=3&t=4266); I needed that extra example to _get it_. Nice solution to work with data on the fly --though I often write programs that use persistence, so I write out to txt file(s). To re-write my solution (for on the fly processing): ` for /f "tokens=2 delims==" %P in ('wmic timezone get StandardName /value') do for /f "delims=" %V in ("%P") do set $UTC_NAME=%V` – David Geeraerts Dec 18 '20 at 16:15