View unanswered posts | View active topics It is currently 28 Nov 2014 11:56



Post new topic Reply to topic  [ 14 posts ] 
SET /P prompt mechanics - New behavior: = makes syntax error 
Author Message
Expert

Joined: 12 Feb 2011 21:02
Posts: 1278
Location: United States (east coast)
Post SET /P prompt mechanics - New behavior: = makes syntax error
I have seen a number of peculiarities documented with how SET /P handles prompts. And there are known differences between XP and later versions of Windows.

We had a significant discussion of the issues at viewtopic.php?p=16857.

Recently I saw a shocking complication posted at http://stackoverflow.com/a/14282332/1012053 that states a SET /P message cannot begin with =. I tested, and David Ruhmann is correct, it results in a syntax error :shock: :(

There doesn't appear to be any way to escape the =. And putting the prompt in a variable and using delayed expansion doesn't help either. :(

I can't believe I've never experienced this before, nor have I seen this documented elsewhere. I imagine someone must have seen this before.

Anyway, I decided to test XP, Vista, and Windows 7 to try to come up with a definitive set of SET /P prompt rules. Here is what I came up with.

Code:

Syntax                |  XP                                 |  Vista and Windows 7
----------------------+-------------------------------------+-------------------------------------
<nul set /p =!msg!    |- If 1st char is quote, then trims   |- Trims leading white space chars.   
       or             |  that quote, and if at least one    |- If 1st non white space char is     
<nul set /p "=!msg!"  |  additional quote, than trims last  |  quote, then that quote is treated 
                      |  quote and all remaining chars.     |  as white space and trimmed, and if
                      |- If 1st non trimmed char is =, then |  at least one additional quote, then
                      |  syntax error.                      |  trims last quote and all remaining
                      |                                     |  chars.
                      |                                     |- If 1st non trimmed char is =, then
                      |                                     |  syntax error.
----------------------+-------------------------------------+-------------------------------------
<nul set /p ="!msg!"  |- Trims leading control chars and    |- Trims leading white space chars.
       or             |  spaces.                            |- If 1st non trimmed char is =, then
<nul set /p "="!msg!""|- If 1st non trimmed char is =, then |  syntax error.
                      |  syntax error.                      |
----------------------+-------------------------------------+-------------------------------------

On Vista and Windows 7, the trimmed leading white space chars are:
    9  0x09  Horizontal Tab
   10  0x0A  New Line
   11  0x0B  Vertical Tab
   12  0x0C  Form Feed
   13  0x0D  Carriage Return
   32  0x20  Space
  255  0xFF  Non-breaking Space


Example                           | XP result            | Vista/Win 7 result
----------------------------------+----------------------+--------------------
<nul set /p = hello world         | [ hello world]       | [hello world]
                                  |                      |
<nul set /p =" hello "world       | [hello ]             | [hello ]
                                  |                      |
<nul set /p "=" hello "world"     | [hello ]             | [hello ]
                                  |                      |
<nul set /p =" " hello "world"    | [" hello "world]     | [" hello "world]
                                  |                      |
<nul set /p "=" " hello "world""  | [" hello "world]     | [" hello "world]
                                  |                      |
<nul set /p = " hello "world      | [ " hello "world]    | [hello ]
                                  |                      |
<nul set /p "= " hello "world"    | [ " hello "world]    | [hello ]
                                  |                      |
<nul set /p = " " hello "world"   | [ " " hello "world"] | [" hello "world]
                                  |                      |
<nul set /p "= " " hello "world"" | [ " " hello "world"] | [" hello "world]
                                  |                      |
<nul set /p ==hello world         | syntax error         | syntax error
                                  |                      |
<nul set /p= =hello world         | [ =hello world]      | syntax error
                                  |                      |
<nul set /p "=" = hello "world"   | syntax error         | syntax error
                                  |                      |
<nul set /p "= " = hello "world"  | [ " = hello "world]  | syntax error

*Note: Square brackets are obviously not in the ouput :)


Note: jeb has posted a great alternative to SET /P :
"Output text without linefeed, even with leading space or =" at http://www.dostips.com/forum/viewtopic.php?f=3&t=4213
:D


Dave Benham


Last edited by dbenham on 16 Jan 2013 10:13, edited 1 time in total.



13 Jan 2013 13:20
Profile

Joined: 10 Feb 2012 02:20
Posts: 4425
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
I found this out here but I didn't clarify it.

viewtopic.php?p=22107#p22107

but SET /p can't handle = and "

A single leading quote doesn't work either.


13 Jan 2013 15:42
Profile
Expert

Joined: 12 Feb 2011 21:02
Posts: 1278
Location: United States (east coast)
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
foxidrive wrote:
I found this out here but I didn't clarify it.

viewtopic.php?p=22107#p22107

but SET /p can't handle = and "

A single leading quote doesn't work either.

Good, you found the = problem as well. :)

But I don't see a problem with " as long as additional quotes are placed appropriately. As I stated in my post, the following both preserve quotes in !msg! (assume delayed expansion enabled)
Code:
<nul set /p ="!msg!"
<nul set /p "="!msg!""


Dave Benham


13 Jan 2013 16:07
Profile

Joined: 10 Feb 2012 02:20
Posts: 4425
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
dbenham wrote:
foxidrive wrote:
A single leading quote doesn't work either.


But I don't see a problem with " as long as additional quotes are placed appropriately.


Try it with just one quote, Dave. It no worky.


13 Jan 2013 16:22
Profile
Expert

Joined: 16 May 2011 08:21
Posts: 1275
Location: Flanders_(Belgium)
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
foxidrive wrote:
Try it with just one quote, Dave. It no worky.
On XP a single quote works as long as additional quotes are placed appropriately,
Code:
><nul set /p ="""
"
>
but '=' character at the beginning is a problem indeed. Next test is funny also :)
Code:
>=
>==
>===
>
No syntax error, but nothing happens either, a valid command that does nothing at all :roll: :?:


13 Jan 2013 16:50
Profile WWW

Joined: 10 Feb 2012 02:20
Posts: 4425
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
Can you make this work? echo "abc ?

Code:
<nul set /p ="abc


13 Jan 2013 16:56
Profile
Expert

Joined: 12 Feb 2011 21:02
Posts: 1278
Location: United States (east coast)
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
foxidrive wrote:
Can you make this work? echo "abc ?

Code:
<nul set /p ="abc

Try reading my post at the top more carefully - it explains the rules.

Yes, your code will strip the quote. But that is not the correct syntax.

If you want to output nearly any message, including quotes, then you need extra quotes enclosing the string after the =.
Code:
<nul set /p =""abc"

The extra quotes are part of the syntax, not part of the message! Nearly any message can be put within the quotes, except for the exceptions listed in my top post.


Dave Benham


13 Jan 2013 17:31
Profile

Joined: 21 Dec 2012 13:36
Posts: 20
Location: United States
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
I have found a solution for the = equals and space trimming issue. However it requires placing a non-display character into the batch script. I do not know if it works on any version of Windows. Only tested on Windows 7.
Code:
<nul set /p =".[0x08]%Var%"

Place any non-space non-issue character followed by the backspace character (illustrated by [0x08]) and only the value of %Var% will display.

Also from what I read here http://www.robvanderwoude.com/type.php, there is an issue with the 0xFF character when the codepage is not 1252.

As noted by foxidrive, Yes this is only a solution for displaying to the screen because the non-displayed characters will be redirected to a file.

BTW: I'm David from Stack Overflow.


Last edited by DigitalSnow on 14 Jan 2013 11:08, edited 2 times in total.



14 Jan 2013 10:44
Profile

Joined: 10 Feb 2012 02:20
Posts: 4425
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
That's probably fine for display purposes but when redirecting into a file it's going to be an issue.


14 Jan 2013 10:48
Profile

Joined: 21 Dec 2012 13:36
Posts: 20
Location: United States
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
Oh, and the reason the equals sign does not work at the beginning, is due to this limitation which is listed in the set /? help documentation.
Quote:
SET command will not allow an equal sign to be part of the name of a variable.

When the first character is set as an equals sign it thinks that we are trying to set the variable name containing an equals sign. This was further made evident as an issue by the leading space trimming in Vista+.


14 Jan 2013 10:57
Profile
Expert

Joined: 12 Feb 2011 21:02
Posts: 1278
Location: United States (east coast)
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
DigitalSnow wrote:
Oh, and the reason the equals sign does not work at the beginning, is due to this limitation which is listed in the set /? help documentation.
Quote:
SET command will not allow an equal sign to be part of the name of a variable.

When the first character is set as an equals sign it thinks that we are trying to set the variable name containing an equals sign. This was further made evident as an issue by the leading space trimming in Vista+.

I suppose that could be true, but it is inconsistent with how the normal SET command works, and nonsensical.

SET "varName==varValue" - the variable name ends at the first = and the 2nd = is included as part of the value.

SET /P "varName==Prompt" - the statement fails because it tries to include the first = in the variable name :?:

Then why does it work if there is an intervening character?

SET /P "varName=x=abc" - the variable name ends at the first = and the remainder is part of the prompt.

I can't see a rational explanation why the prompt cannot begin with =. I should think the variable name should always end at the first =, and the remainder should be the prompt. But then batch is full of irrational quirks and hacks. :evil:


Dave Benham


14 Jan 2013 22:47
Profile

Joined: 20 Aug 2010 13:57
Posts: 371
Location: Chile
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
A fix for the problem:
Code:
@Echo Off
For /F %%# in ('"Prompt;$H;&For %%_ in (1) Do Rem"'
) Do Set "\b=%%#"
Set /P "=%\b%=Equal" <Nul
Pause >Nul


15 Jan 2013 02:18
Profile WWW

Joined: 10 Feb 2012 02:20
Posts: 4425
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
carlos wrote:
A fix for the problem:


It's only a fix for displaying. If you redirect into a file then it will have a leading hex 08 character.


15 Jan 2013 02:37
Profile

Joined: 21 Dec 2012 13:36
Posts: 20
Location: United States
Post Re: SET /P prompt mechanics - New behavior: = makes syntax e
dbenham wrote:
DigitalSnow wrote:
Oh, and the reason the equals sign does not work at the beginning, is due to this limitation which is listed in the set /? help documentation.
Quote:
SET command will not allow an equal sign to be part of the name of a variable.

When the first character is set as an equals sign it thinks that we are trying to set the variable name containing an equals sign. This was further made evident as an issue by the leading space trimming in Vista+.

I suppose that could be true, but it is inconsistent with how the normal SET command works, and nonsensical.

SET "varName==varValue" - the variable name ends at the first = and the 2nd = is included as part of the value.

SET /P "varName==Prompt" - the statement fails because it tries to include the first = in the variable name :?:

Then why does it work if there is an intervening character?

SET /P "varName=x=abc" - the variable name ends at the first = and the remainder is part of the prompt.

I can't see a rational explanation why the prompt cannot begin with =. I should think the variable name should always end at the first =, and the remainder should be the prompt. But then batch is full of irrational quirks and hacks. :evil:


Dave Benham

I agree that it is inconsistent. You would think that set would parse the variable name using the same method for both set [variable=[string]] and set /p variable=[promptString], but sadly that is not the case. :( Nor does it appear to have ever been the case. My guess is that the programmers who wrote set did not use the same function for parsing the string as they did with the promptString.


15 Jan 2013 07:49
Profile
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 


Who is online

Users browsing this forum: Bing [Bot], Yahoo [Bot] and 16 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Forum style by Vjacheslav Trushkin for Free Forums/DivisionCore.