How can I get a password containing a caret (^) pa

2020-08-11 01:54发布

问题:

Summary:
From the command line (on Windows Server 2003 R2), I type:

> SET password=a^b  
> ECHO %password%

And the result is "ab". Where'd the freakin caret (^) go? I then attempted to "escape" it with ^^, `^, %^, ^^^, and none of these worked to ever have a caret pass through to the echo command. This batch file is in the middle. So, I can neither change the source system's password to avoid using the caret, nor can I change the target system's password to be out of sync with the source system.

Details:
I searched Google and then SO. And while I now have a bazillion tips on how to better engineer my bloody Windows batch file, my problem remains.

I have a batch file, called run.bat, which consists of a series of SET statements setting up the context for running a Java command line application. After "cd"ing to the proper folder, at the prompt on the command line (on Windows Server 2003 R2) I type:

> run the_name the_pass^word

When I look at the output echoed to the command line, I see "java...config.user_name=the_name config.password=the_password" where the ... is a bunch of parameters and libraries noise not relevant to this problem. The bloody caret (^) has disappeared.

I have tried every kind of escaping strategy I could find trying to get the caret to show up. I have not been able to find anything that will cause the caret to appear...except surrounding the password with quote, as in I type:

> run the_name "the_pass^word"

...and then the resulting command line looks like:

java...config.user_name=the_name config.password="the_pass^word"

i.e. I get the caret, but the quotes are now appearing IN the content of the string...which naturally doesn't work for the application to which they are being passed.

Does anyone have an obvious tip or trick I have missed to have what is typed in as parameters on the command line passed through UNTOUCHED to my internal utilization? The value is in fact arriving in the batch file variable of %2. But, it's been "defrocked" by the time I get to see the contents of %2 the first time.

UGH, I'm no fan of Windows batch files.

Update:
A big thanks to Joshua McKinnon's response. I selected his as the answer as it solved my immediate problem. However, I wanted to elaborate further on the solutions (yes, plural).

  1. No need to use any form of SetLocal/EndLocal
  2. Must use the %~1 style syntax - found no form of the %1 syntax which worked to preserve the caret
  3. Solution: Unquoted, use 4 consecutive carets (ex: use pass^^^^word to produce pass^word)
  4. Solution: Quoted, use 2 consecutive carets (ex: use "pass^^word" to produce pass^word)

Within the batch file "run.bat", use the %~1 syntax as in:

java MyClass username=%~1 password=%~2

...and then at the command line, type:

> run mr_clean puke^^^^boy  

or

> run mr_clean "puke^^boy"  

which will then result in the final executed statement to look like:

java MyClass username=mr_clean password=puke^boy  

Hope this helps other save some time. I ended up on 6 hours of tangents trying to hunt down this idiosyncrasy (more like idiot-synchronicity).

回答1:

According to this page, & | ( < > ^ are all reserved characters in windows batch files. ^ is an escape character, as well as line continuation character. ^^ should give you a ^, but then that ^ may need to be escaped.

To get a password through the input, have you tried quadrupling the number of carets?

e.g.:  my_batch.cmd the_pass^^^^word


回答2:

This explains the problem:

http://www.robvanderwoude.com/battech_inputvalidation_commandline.php

If you process some arbitrary strings in batch file / CMD script, don't pass it through command line arguments! Instead, put them into a file and let the batch file read it. Because validation and sanitization in command line arguments is never fool-proof.



回答3:

The main problem is that carets and other special characters are handled always, when they are found in a line (outside of quotes).
The content is parsed also when it is expanded by %var%, but not for the delayed expansion with !var!

Sample

@echo off
setlocal Enabledelayedexpansion

set variabl=-^^"^^-
set variabl
echo delayed !variabl!
echo percent %variabl%

--- Output ---
variabl=-^"^^-
delayed -^"^^-
percent -"^-

The content of variabl is -^"^^-, that is the problem of the set line. But the carets are only works as escape characters again, when using them with %var%.



回答4:

It might be easier to strip off the quotes. See this SO link for some info.