|
I hate cmd.exe
Last post 04-09-2008 5:25 PM by Vanders. 90 replies.
-
04-02-2008 4:38 PM
|
|
-
aogail


- Joined on 04-02-2008
- Posts 11
|
set foo=bar
if "true" == "true" (
set foo=baz
echo %foo% should equal baz
)
...but it doesn't.
|
|
-
-
dabean


- Joined on 02-26-2008
- Posts 25
|
set foo=bar if "true" == "true" set foo=baz echo %foo% should equal baz
It's not exactly a full-fledged programming language.
|
|
-
-
AbbydonKrafts


- Joined on 11-21-2006
- Carrollton, GA, USA
- Posts 1,022
|
It is funny like that:
set foo=bar
if "true" == "true" (
set foo=baz
@echo Inside if: foo=%foo%
)
@echo Outside if: foo=%foo%
Results in:
C:\>set foo=bar
C:\>if "true" == "true" (
set foo=baz
)
Inside if: foo=bar
Outside if: foo=baz
Join us at #TDWTF on irc.slashnet.org !
|
|
-
-
-
AbbydonKrafts


- Joined on 11-21-2006
- Carrollton, GA, USA
- Posts 1,022
|
Looks like it has to go all the way back to the base level. This:
set foo=bar
if "true" == "true" (
if "true" == "true" (
set foo=baz
@echo Inside if #2: foo=%foo%
)
@echo Inside if #1: foo=%foo%
)
@echo Outside if: foo=%foo%
Still only works when it gets back to the base level:
C:\>set foo=bar
C:\>if "true" == "true" (
if "true" == "true" (
set foo=baz
)
)
Inside if #2: foo=bar
Inside if #1: foo=bar
Outside if: foo=baz
Join us at #TDWTF on irc.slashnet.org !
|
|
-
-
-
belgariontheking


- Joined on 08-20-2007
- Cincinnati, OH, USA
- Posts 1,365
|
CDarklock:How odd. I'm going to go off and play with this for a while.
<channeling person="Michael Scott">That's what she said!</channeling>
I guess I'm back.
Please continue to spam the addresses below.
PLEASE SPAM: jtobin@ohioinstituteofhealthcareers.edu jtobin@ohiobusinesscollege.edu
|
|
-
-
CDarklock


- Joined on 07-27-2006
- Posts 311
|
My son says that all the time. He's almost four.
He also does the "You know what? Chicken butt!" joke.
|
|
-
-
AbbydonKrafts


- Joined on 11-21-2006
- Carrollton, GA, USA
- Posts 1,022
|
CDarklock:How odd. I'm going to go off and play with this for a while.
I have this odd feeling that I'm going to spend time at least once a week trying to think up some insane batch files that do not rely on new-fangled technology such as scripts. I remember creating some beasts back on DOS 6.
I guess it'll make good fodder for my new tech blog (trying to keep topics separate now).
Join us at #TDWTF on irc.slashnet.org !
|
|
-
-
El_Heffe


- Joined on 11-08-2007
- Posts 114
|
aogail:set foo=bar if "true" == "true" ( set foo=baz echo %foo% should equal baz )
...but it doesn't.
cmd.exe is crippled and retarded and doesn't support what you're trying to do. However, your batch file works perfectly as-is with 4NT.exe from jpsoft.comApprently they've changed the name to "Take Command Console" with the most recent version. I've been using this program for many years -- going all the way back to their 4DOS program back in the early 90's.. I have no association with them -- just a satisfied customer for 15 years.
|
|
-
-
dabean


- Joined on 02-26-2008
- Posts 25
|
aogail: dabean:It's not exactly a full-fledged programming language.
That's a pretty poor excuse for failing to read the correct value of a variable inside an if block. ;P
Sorry, didn't read the question properly. Set /? provides explanation: Finally, support for delayed environment variable expansion has been added. This support is always disabled by default, but may be enabled/disabled via the /V command line switch to CMD.EXE. See CMD /?
Delayed environment variable expansion is useful for getting around the limitations of the current expansion which happens when a line of text is read, not when it is executed. The following example demonstrates the problem with immediate variable expansion:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
would never display the message, since the %VAR% in BOTH IF statements is substituted when the first IF statement is read, since it logically includes the body of the IF, which is a compound statement. So the IF inside the compound statement is really comparing "before" with "after" which will never be equal. Similarly, the following example will not work as expected:
set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST%
in that it will NOT build up a list of files in the current directory, but instead will just set the LIST variable to the last file found. Again, this is because the %LIST% is expanded just once when the FOR statement is read, and at that time the LIST variable is empty. So the actual FOR loop we are executing is:
for %i in (*) do set LIST= %i
which just keeps setting LIST to the last file found.
Delayed environment variable expansion allows you to use a different character (the exclamation mark) to expand environment variables at execution time. If delayed variable expansion is enabled, the above examples could be written as follows to work as intended:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked )
set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%
|
|
-
-
WeatherGod


- Joined on 04-19-2006
- Posts 274
|
dabean: ..snip full explanation... so, who is on first again?
|
|
-
-
aogail


- Joined on 04-02-2008
- Posts 11
|
Wow, thanks dabean; I did not expect the cmd.exe help to include an explanation of this insane behavior. The fact that cmd.exe /V exists actually makes this even more of a WTF than it was originally.
Let me get this straight. MS:
- implemented stupid, arguably buggy behavior in their variable expansion code;
- decided to "fix" the buggy behavior, but only if you invoke cmd.exe with a brand new argument; and
- decided not only would you need to invoke cmd.exe with /V, but in doing so you would have to write scripts that use syntax that is invalid under normal cmd.exe operation
W.T.F.
|
|
-
-
Eternal Density


- Joined on 03-25-2007
- Posts 306
|
WeatherGod: dabean: ..snip full explanation... so, who is on first again?
I don't know
300 posts! This is Spar... dang I just lost the game. Legendary Threadlolwtf: Instead of comfy chair, package contained bobcat. Would not buy again. curtmack: It's like Godwin's Law, but instead of Hitler it's xkcd references. morbiuswilters: Right, but the Holocaust wasn't nearly as bad as xkcd.
|
|
-
-
Spacecoyote


- Joined on 01-14-2007
- Posts 69
|
cmd.exe is the product of years of laziness and back-burner development at microsoft.
DOS started out a clone of CP/M. Microsoft didn't bother with multitasking or even anything above primitive batch processing, and instead just threw BASIC on there as DOS's "killer app". Oddly enough, both the IBM PC and BASIC took off, carrying DOS with it. By then MS had a more fully featured Unix clone called Xenix (based on Version 7 Unix), but DOS had become so big and Microsoft were looking at OS/2 so Xenix was abandoned by Microsoft (SCO picked it up and went on to become infamous).
The Macintosh was doing big things for Apple, and threatening to slowly but surely kill the IBM PC. It seemed almost too late when Microsoft stepped in and released Windows 3, their first offering to even come close to the user friendliness of the Mac, with DOS as sort of a glorified bootloader. But due to the sheer size of the IBM PC market Windows took off. So the big thing was GUI and Microsoft didn't make any noteworthy improvements since to the command prompt. Recently Microsoft has released Windows Powershell, a more more fully featured shell than cmd.exe, but non-standard (unless you call vbscript a standard) to say the least. I say screw both of them. BASH ftw!
|
|
-
-
lolwtf


- Joined on 04-02-2008
- (null)
- Posts 146
|
The real WTF is no Unicode support.
(null)
|
|
-
-
Pidgeot


- Joined on 09-19-2007
- Posts 71
|
aogail:
- decided to "fix" the buggy behavior, but only if you invoke cmd.exe with a brand new argument; and
- decided not only would you need to invoke cmd.exe with /V, but in doing so you would have to write scripts that use syntax that is invalid under normal cmd.exe operation
Microsoft are INSANE about backwards compatibility. This way, a legacy script will only produce a different result if it tries to use !varname!, and varname is a variable that exists (a situation they clearly deem less likely than a script relying on the old behavior).
I'm not saying that necessarily makes the solution good, or any less of a WTF, but this is pretty much what they do for any change that has the possibility to break something - and if the goal is to maximize backwards compatibility, I don't see how they could have done things any differently.
Of course, since you wouldn't be writing a script that relies on !-expansion without knowing this requires /V, it would be trivial to make your script launch a new cmd.exe process with the appropriate parameters, if /V is not activated:
set SOMESPECIALVARNAME=test if not "!SOMESPECIALVARNAME!" == "test" ( cmd /v /c %0 %* goto EOF ) rem Insert your script here
You might want to add a check to ensure that it doesn't go into an infinite loop if run on a system that doesn't support it, and possibly define your own label, but this should run unmodified on XP and later (don't know about Win2000).
lolwtf:The real WTF is no Unicode support.
Actually, it supports Unicode just fine, it's just that Lucida Console doesn't contain Unicode characters, and there is no font link defined, so Windows doesn't know what font to use instead. I've set up Vista to use Meiryo for Japanese characters in the shell, and it works great (you can do this with XP as well, but due to the design of MS Gothic, it doesn't render properly) - all that's needed is an entry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink and a reboot.
Programs (at least those that aren't part of Windows), however, tend to not support it, even though UTF-8 is available as a codepage you can change to (chcp 65001).
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 191
|
It's very simple. Environment variables are interpolated before the command is executed. Consider the following Perl snippet:
$foo = 'bar';
$command = <<IF;
if ('true' == 'true') {
$foo = 'baz';
print "$foo should be equal to baz";
}
IF
print $command;
This outputs:
if ('true' == 'true') {
bar = 'baz';
print "bar should be equal to baz";
}
Which obviously won't eval in Perl, but I'm sure you get the point.
rpar PROTON all
|
|
-
-
KenW


- Joined on 07-19-2005
- Posts 422
|
aogail:Wow, thanks dabean; I did not expect the cmd.exe help to include an explanation of this insane behavior. The fact that cmd.exe /V exists actually makes this even more of a WTF than it was originally.
Let me get this straight. MS:
- implemented stupid, arguably buggy behavior in their variable expansion code;
- decided to "fix" the buggy behavior, but only if you invoke cmd.exe with a brand new argument; and
- decided not only would you need to invoke cmd.exe with /V, but in doing so you would have to write scripts that use syntax that is invalid under normal cmd.exe operation
W.T.F. Let me get this straight. MS: - implemented new functionality to overcome a shortcoming that has existed for decades;
- did so in a way that maintains backward compatibility so that existing batch files don't break;
- documented the change thoroughly enough that even you should have been able to understand it.
And you still complain about it. What an ass.
|
|
-
-
DaveK


- Joined on 02-22-2006
- Posts 471
|
Eternal Density: WeatherGod: dabean: ..snip full explanation... so, who is on first again? I don't know
EPIC FAIL
It's supposed to go: WeatherGod: dabean: ..snip full explanation... so, who is on first again?
No, who's on second.
Now get your ass back to school and learn yourself some culture!
|
|
-
-
MasterPlanSoftware


- Joined on 11-10-2006
- Posts 108
|
KenW:And you still complain about it. What an ass. Agreed. Looks like we have picked up another MS bashing troll with nothing intelligent to even argue about. We can just blame MFD for attracting them! </sarcasm>
|
|
-
-
morbiuswilters


- Joined on 01-15-2008
- East Coast Represent!
- Posts 2,978
|
Spacecoyote:cmd.exe is the product of years of laziness and back-burner development at microsoft.
DOS started out a clone of CP/M. Microsoft didn't bother with multitasking or even anything above primitive batch processing, and instead just threw BASIC on there as DOS's "killer app". Oddly enough, both the IBM PC and BASIC took off, carrying DOS with it. By then MS had a more fully featured Unix clone called Xenix (based on Version 7 Unix), but DOS had become so big and Microsoft were looking at OS/2 so Xenix was abandoned by Microsoft (SCO picked it up and went on to become infamous).
The Macintosh was doing big things for Apple, and threatening to slowly but surely kill the IBM PC. It seemed almost too late when Microsoft stepped in and released Windows 3, their first offering to even come close to the user friendliness of the Mac, with DOS as sort of a glorified bootloader. But due to the sheer size of the IBM PC market Windows took off. So the big thing was GUI and Microsoft didn't make any noteworthy improvements since to the command prompt. Recently Microsoft has released Windows Powershell, a more more fully featured shell than cmd.exe, but non-standard (unless you call vbscript a standard) to say the least. I say screw both of them. BASH ftw!
Aw, fuck, we've already been through this. Batch scripts kind of suck, but you should probably just use vbscript or one of the other standard MS languages. DOS didn't support multitasking because even single tasking was pretty sophisticated for the consumer market at the time. DOS wasn't competing with UNIX mainframes or minicomputers. Bash is a stronger shell because UNIX has a stronger command-line legacy, but it's still pretty shitty for anything but the most trivial programs. If my bash script is going to be longer than 10 lines, I will usually just use perl.
< pstorer> Bans don't mean shit on the forum. It's like being on the Sex Offender List. You can still entice kids into your van with candy.
Want more? Go the IRC channel #TDWTFMafia on irc.slashnet.org.
Farmer Brown is MasterPlanSoftware. He created a new forum account because he is obsessed with me after I scorned him. Ignoring his trolling is the best way to deal with the crybaby.
|
|
-
-
aogail


- Joined on 04-02-2008
- Posts 11
|
MasterPlanSoftware: KenW:And you still complain about it. What an ass. Agreed. Looks like we have picked up another MS bashing troll with nothing intelligent to even argue about. We can just blame MFD for attracting them! </sarcasm>
Hooray for MS apologists.
Do you really love MS so much that you overlook even this ridiculous behavior? No one in their right mind would expect a shell to not properly support variable changes inside if blocks. By the way, adding new and incompatible syntax to work around a bug doesn't count as fixing the bug.
|
|
-
|
|