{"id":26704,"date":"2022-09-27T00:01:00","date_gmt":"2022-09-26T22:01:00","guid":{"rendered":"http:\/\/159.69.82.204\/win\/?p=26704"},"modified":"2022-09-26T23:17:46","modified_gmt":"2022-09-26T21:17:46","slug":"windows-batch-files-strange-behavior-of-the-if-command","status":"publish","type":"post","link":"https:\/\/borncity.com\/win\/2022\/09\/27\/windows-batch-files-strange-behavior-of-the-if-command\/","title":{"rendered":"Windows batch files: Strange behavior of the IF command"},"content":{"rendered":"<p><img decoding=\"async\" title=\"Windows\" style=\"margin: 0px 10px 0px 0px\" alt=\"Windows\" src=\"https:\/\/www.borncity.com\/blog\/wp-content\/uploads\/2021\/04\/Windows-klein.jpg\" width=\"200\" align=\"left\">[<a href=\"https:\/\/www.borncity.com\/blog\/2022\/09\/26\/windows-batch-dateien-seltsames-verhalten-des-if-befehls\/\" target=\"_blank\" rel=\"noopener\">German<\/a>]German blog reader Frank contacted me about a problem on Windows that I don't really have an explanation for. Originally it was about the IF command in batch files returning wrong values when comparing. So Frank tested the whole thing with PowerShell and found something similar there. Only a test program written with VB .NET delivered the expected results. Since the batch program also delivers the same, incorrect, results under Windows 7, I assume that Frank and I have overlooked something. I'll post the problem here in the blog &#8211; maybe a reader will notice something. <\/p>\n<p><!--more--><\/p>\n<h2>Problem: Incorrect batch evaluation<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"https:\/\/vg05.met.vgwort.de\/na\/c3033dc0f76e4c4e96b241c86932d1e3\" width=\"1\" height=\"1\">German blog reader Frank S. recently contacted me by e-mail and wrote me about his problem in using the IF command with batch files. Frank wrote: <\/p>\n<blockquote>\n<p>I keep stumbling across strange things in windows. Today I wanted to implement a batch program where I have to compare letters on \"greater than\" or \"less than\". This can involve lowercase letters as well as uppercase letters. <\/p>\n<p>The program behaved completely absurdly, so I got to the bottom of it and finally realized that the \"if\" command with the extended compare commands behaves as if I used the \"\/I\" option, which I did not. I have created a small example program here that shows the strange behavior.<\/p>\n<\/blockquote>\n<p>Frank provided me with the following source code of the batch script. <\/p>\n<pre><code>\n@echo off\nsetlocal enableextensions\nif A == a (\necho A == a : True [Wrong!]\n) else (\necho A == a : False [OK]\n)\nif A EQU a (\necho A EQU a : True [Wrong!]\n) else (\necho A EQU a : False [OK]\n)\nif A LSS b (\necho A LSS b : True [OK]\n) else (\necho A LSS b : False [Wrong!]\n)\nif A LEQ b (\necho A LEQ b : True [OK]\n) else (\necho A LEQ b : False [Wrong!]\n)\nif A GTR b (\necho A GTR b : True [Wrong!]\n) else (\necho A GTR b : False [OK]\n)\nif A GEQ b (\necho A GEQ b : True [Wrong!]\n) else (\necho A GEQ b : False [OK]\n)\nif a LSS B (\necho a LSS B : True [Wrong!]\n) else (\necho a LSS B : False [OK]\n)\nif a LEQ B (\necho a LEQ B : True [Wrong!]\n) else (\necho a LEQ B : False [OK]\n)\nif a GTR B (\necho a GTR B : True [OK]\n) else (\necho a GTR B : False [Wrong!]\n)\nif a GEQ B (\necho a GEQ B : True [OK]\n) else (\necho a GEQ B : False [Wrong!]\n)\nif Z LSS a (\necho Z LSS a : True [OK]\n) else (\necho Z LSS a : False [Wrong!]\n)\nif ALPHA LSS alpha (\necho ALPHA LSS alpha : True [OK]\n) else (\necho ALPHA LSS alpha : False [Wrong!]\n)\nif ALPHA LEQ alpha (\necho ALPHA LEQ alpha : True [OK]\n) else (\necho ALPHA LEQ alpha : False [Wrong!]\n)\nif ALPHA GTR alpha (\necho ALPHA GTR alpha : True [Wrong!]\n) else (\necho ALPHA GTR alpha : False [OK]\n)\nif ALPHA GEQ alpha (\necho ALPHA GEQ alpha : True [Wrong!]\n) else (\necho ALPHA GEQ alpha : False [OK]\n)\nPause<\/code><\/pre>\n<p>Frank wrote that he ran this batch file on Windows 10 with the latest patch level (V10.0.19044.2006) and got the following output. <\/p>\n<p><pre><code>\nA == a : False [OK]\nA EQU a : False [OK]\nA LSS b : True [OK]\nA LEQ b : True [OK]\nA GTR b : False [OK]\nA GEQ b : False [OK]\na LSS B : True [Wrong!]\na LEQ B : True [Wrong!]\na GTR B : False [Wrong!]\na GEQ B : False [Wrong!]\nZ LSS a : False [Wrong!]\nALPHA LSS alpha : False [Wrong!]\nALPHA LEQ alpha : False [Wrong!]\nALPHA GTR alpha : True [Wrong!]\nALPHA GEQ alpha : True [Wrong!]<\/code><\/pre>\n<p>The <em>Extended<\/em> comparisons ignore upper or lower case. The character a is numerically greater than a B or an A in ANSI and Unicode. Frank writes that the commands behave as if the \/I option had been specified. However, it is unclear why <em>ALPHA GTR<\/em> alpha gives the result True. Only the comparisons == and EQU behave correctly. <\/p>\n<p><img decoding=\"async\" title=\"IF-Vergleich\" alt=\"IF-Vergleich\" src=\"https:\/\/i.imgur.com\/bJ6gkY2.png\"> <\/p>\n<p>I ran the whole thing on Windows 7 SP1 and get the same result &#8211; so it doesn't depend on Windows 10. There must be some kind of thinking error. Frank wrote me in response to the question about a thinking error: <\/p>\n<blockquote>\n<p>That was also my first thought. But I can't find anything. I have now tested the whole thing with 3 different programming languages: <\/p>\n<p>1. Batch<br \/>2. PowerShell<br \/>3. VB .NET <\/p>\n<p>The two scripting languages both give the same wrong result. So it is not a problem of Batch alone. VB .NET does it right.<\/p>\n<\/blockquote>\n<p>Here are the source codes of the test programs in question, which write the results to an output window with an encoding for CodePage850. <\/p>\n<p><strong>Batch program<\/strong> <\/p>\n<p><pre><code>@echo off\n<p>setlocal enableextensions enabledelayedexpansion\n<p>set alphabet=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc\u00e4\u00f6\u00fc\u00df\n<p>set pos=0\n<p>:mainLoop\n<p>set char=!alphabet:~%pos%,1!\n<p>if A%char% == A goto :endProc\n<p>echo.\n<p>set pos2=0\n<p>:innerLoop\n<p>set char2=!alphabet:~%pos2%,1!\n<p>if A%char2% == A goto :nextMain\n<p>call :testChar %char% %char2%\n<p>set \/a pos2=pos2+1\n<p>goto :innerLoop\n<p>:nextMain\n<p>set \/a pos=pos+1\n<p>goto :mainLoop\n<p>:testChar\n<p>if %1 lss %2 echo %1 ^&lt;&nbsp; %2\n<p>if %1 leq %2 echo %1 ^&lt;= %2\n<p>if %1 gtr %2 echo %1 ^&gt;&nbsp; %2\n<p>if %1 geq %2 echo %1 ^&gt;= %2\n<p>exit \/b\n<p>:endProc<\/code><\/p><\/pre>\n<p><strong>PowerShell script<\/strong> <\/p>\n<p><pre><code>function Test-Char\n<p>{\n<p>Param\n<p>(\n<p>[Parameter(Mandatory=$true, Position=0)]\n<p>[string] $Char1,\n<p>[Parameter(Mandatory=$true, Position=1)]\n<p>[string] $Char2\n<p>)\n<p>if ($Char1 -clt $Char2) {\n<p>Write-Output \"$Char1 &lt;&nbsp; $Char2\"\n<p>}\n<p>if ($Char1 -cle $Char2) {\n<p>Write-Output \"$Char1 &lt;= $Char2\"\n<p>}\n<p>if ($Char1 -cgt $Char2) {\n<p>Write-Output \"$Char1 &gt;&nbsp; $Char2\"\n<p>}\n<p>if ($Char1 -cge $Char2) {\n<p>Write-Output \"$Char1 &gt;= $Char2\"\n<p>}\n<p>}\n<p>$PSDefaultParameterValues['Out-File:Encoding'] = 'oem'\n<p>$alphabet=\"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc\u00e4\u00f6\u00fc\u00df\"\n<p>for($pos1=0; $pos1 -lt $alphabet.Length; $pos1++) {\n<p>Write-Output \"\"\n<p>for($pos2=0; $pos2 -lt $alphabet.Length; $pos2++) {\n<p>Test-Char $alphabet.Substring($pos1, 1) $alphabet.Substring($pos2, 1)\n<p>}\n<p>}<\/code><\/p><\/pre>\n<p><code><br \/><\/code><strong>VB .NET<\/strong> <\/p>\n<p><pre><code>\nImports System\nModule Program\nSub Main(args As String())\nDim alphabet As String = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6\u00dc\u00e4\u00f6\u00fc\u00df\"\nFor pos1 As Integer = 0 To alphabet.Length - 1\nConsole.WriteLine()\nFor pos2 As Integer = 0 To alphabet.Length - 1\nTestChar(alphabet.Substring(pos1, 1), alphabet.Substring(pos2, 1))\nNext pos2\nNext pos1\nEnd Sub\nPrivate Sub TestChar(char1 As String, char2 As String)\nIf char1 &lt; char2 Then _\nConsole.WriteLine($\"{char1} &lt;  {char2}\")\nIf char1 &lt;= char2 Then _\nConsole.WriteLine($\"{char1} &lt;= {char2}\") If char1 &gt; char2 Then _\nConsole.WriteLine($\"{char1} &gt;  {char2}\")\nIf char1 &gt;= char2 Then _\nConsole.WriteLine($\"{char1} &gt;= {char2}\")\nEnd Sub\nEnd Module\n<\/code><\/pre>\n<p>Therefore, I would like to ask the readers if anyone can think of an ad hoc explanation for this. First <a href=\"https:\/\/www.borncity.com\/blog\/2022\/09\/26\/windows-batch-dateien-seltsames-verhalten-des-if-befehls\/\" target=\"_blank\" rel=\"noopener\">reactions<\/a> within my German blog, people are puzzled about that issue.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[German]German blog reader Frank contacted me about a problem on Windows that I don't really have an explanation for. Originally it was about the IF command in batch files returning wrong values when comparing. So Frank tested the whole thing &hellip; <a href=\"https:\/\/borncity.com\/win\/2022\/09\/27\/windows-batch-files-strange-behavior-of-the-if-command\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[194],"class_list":["post-26704","post","type-post","status-publish","format-standard","hentry","category-windows","tag-windows"],"_links":{"self":[{"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/posts\/26704","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/comments?post=26704"}],"version-history":[{"count":0,"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/posts\/26704\/revisions"}],"wp:attachment":[{"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/media?parent=26704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/categories?post=26704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/borncity.com\/win\/wp-json\/wp\/v2\/tags?post=26704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}