{"id":96715,"date":"2017-07-31T07:00:00","date_gmt":"2017-07-31T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96715"},"modified":"2019-03-13T01:14:41","modified_gmt":"2019-03-13T08:14:41","slug":"20170731-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170731-00\/?p=96715","title":{"rendered":"The redirection can come anywhere on the line, so watch out for those spaces"},"content":{"rendered":"<p>Wekcome to Batch File Week. Batch is probably one of the most hated programming languages that people are still writing new programs in. You hate it, but you have to deal with it. So just <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20160329-00\/?p=93214\">deal with it<\/a>. <\/p>\n<p>That said, here we go. <\/p>\n<p>A customer couldn&#8217;t understand why parenthesizing a few <code>ECHO<\/code> statements resulted in a syntax error. <\/p>\n<blockquote CLASS=\"q\">\n<p>This version of the batch file works: <\/p>\n<pre>\n@echo off\nset log=C:\\Space Path\n\necho Test &gt;&gt;%log%\\Output.txt\necho Redirection &gt;&gt;%log%\\Output.txt\n<\/pre>\n<p>On the other hand, this version, which should be equivalent, spits out a syntax error. <\/p>\n<pre>\n@echo off\nset log=C:\\Space Path\n\n(\n  echo Test\n  echo Redirection\n) &gt;&gt;%log%\\Output.txt\n<\/pre>\n<p>The error is <\/p>\n<pre>\nPath\\Output.txt was unexpected at this time.\n<\/pre>\n<p>If the syntax of the second command is illegal, then so too should the first, since they are basically the same thing. Why is one legal and the other not? <\/p>\n<\/blockquote>\n<p>Recall that <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2006\/05\/18\/600962.aspx\">you&#8217;re allowed to put the redirection operator anywhere on the line<\/a>, and when it is parsed, it is removed from the command line, and what remains needs to be a legal command. <\/p>\n<p>In the first batch file, the <code>echo<\/code> statement expands to <\/p>\n<pre>\necho Test <font COLOR=\"red\">&gt;&gt;C:\\Space<\/font> Path\\Output.txt\n<\/pre>\n<p>The redirection operator detector takes out the redirection operator and the file name (which due to the embedded space is parsed as merely <code>C:\\Space<\/code>), leaving <\/p>\n<pre>\necho Test Path\\Output.txt\n<\/pre>\n<p>Result: The string <code>Test Path\\Output.txt<\/code> is placed into the file <code>C:\\Space<\/code>. <\/p>\n<p>Now let&#8217;s look at the second batch file. The command being parsed is <\/p>\n<pre>\n(\n  echo Test\n  echo Redirection\n) &gt;&gt;%log%\\Output.txt\n<\/pre>\n<p>which expands to <\/p>\n<pre>\n(\n  echo Test\n  echo Redirection\n) <font COLOR=\"red\">&gt;&gt;C:\\Space<\/font> Path\\Output.txt\n<\/pre>\n<p>Again, the redirection operator detector takes out the redirection operator and the file name, leaving <\/p>\n<pre>\n(\n  echo Test\n  echo Redirection\n) Path\\Output.txt\n<\/pre>\n<p>And that is a syntax error. <\/p>\n<p>In other words, the first batch file works because the extra junk you appended happened to be in a place where junk was legal. (It gets treated as more arguments to the <code>ECHO<\/code> command.) But the second batch file puts the extra junk in a place where junk is not legal, and so it is rejected as a syntax error. <\/p>\n<p>If you take a step back, you&#8217;ll see that the real problem is that the batch file uses a path with spaces but fails to quote it properly. <\/p>\n<p>Whose idea was it to allow redirection operators to appear anywhere in the line? Answer: Ken Thompson, in <a HREF=\"http:\/\/www.in-ulm.de\/~mascheck\/bourne\/v2\/\">version&nbsp;2 of <code>sh<\/code><\/a>. If you think this is a stupid feature, <a HREF=\"http:\/\/www.cs.bell-labs.com\/who\/ken\/\">you can let him know<\/a>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The operator vanishes.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-96715","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The operator vanishes.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96715","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=96715"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96715\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=96715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}