如何获取包含插入符号 (^) 的密码,将其作为参数原封不动地传递给 Windows 批处理文件?
摘要:
在命令行(在 Windows Server 2003 R2 上)中,我键入:
> SET password=a^b
> ECHO %password%
结果是“ab”。奇怪的插入符 (^) 去哪儿了?然后我尝试用 ^^、`^、%^、^^^ 来“转义”它,但这些都没有使插入符号传递到 echo 命令。这个批处理文件位于中间。因此,我既无法更改源系统的密码以避免使用插入符号,也无法更改目标系统的密码以使其与源系统不同步。
详细信息:
我搜索了谷歌,然后就这样了。虽然我现在有无数关于如何更好地设计我该死的 Windows 批处理文件的技巧,但我的问题仍然存在。
我有一个名为 run.bat 的批处理文件,它由一系列设置运行 Java 命令行应用程序的上下文的 SET 语句组成。在“cd”到正确的文件夹后,在命令行提示符处(在 Windows Server 2003 R2 上),我键入:
> run the_name the_pass^word
当我查看回显到命令行的输出时,我看到“java...config.user_name= the_name config.password=the_password" 其中...是一堆与此问题无关的参数和库噪音。该死的插入符 (^) 消失了。
我尝试了各种我能找到的转义策略,试图让插入符号出现。我无法找到任何会导致插入符号出现的内容...除了用引号包围密码,如我键入:
> run the_name "the_pass^word"
...然后生成的命令行如下所示:
java...config.user_name=the_name config.password="the_pass^word"
即我得到插入符号,但是引号现在出现在字符串的内容中......这自然不适用于它们所传递到的应用程序。
有没有人有一个明显的提示或技巧,我错过了将命令行上作为参数输入的内容通过未触及的方式传递到我的内部使用?该值实际上已到达 %2 的批处理文件变量中。但是,当我第一次看到 %2 的内容时,它已经“解除锁定”了。
呃,我不喜欢 Windows 批处理文件。
更新:
非常感谢约书亚·麦金农的回应。我选择他作为答案,因为它解决了我眼前的问题。但是,我想进一步详细说明解决方案(是的,复数)。
- 不需要使用任何形式的 SetLocal/EndLocal
- 必须使用 %~1 样式语法 - 没有发现任何形式的 %1 语法可以保留插入符号
- 解决方案:不加引号,使用 4 个连续的插入符号(例如:使用 pass^^^^ 解决方案:引用,使用 2 个连续的插入符号
- (例如:使用“pass^^word”生成 pass^word)
在批处理文件“run.bat”中,使用 %~1 语法,如下所示:
java MyClass username=%~1 password=%~2
...然后在命令行中键入:
> run mr_clean puke^^^^boy
或
> run mr_clean "puke^^boy"
然后将导致最终执行的语句如下所示:
java MyClass username=mr_clean password=puke^boy
希望这可以帮助其他人节省一些时间。我花了 6 个小时的时间试图找出这种特质(更像是白痴同步性)。
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).
- No need to use any form of SetLocal/EndLocal
- Must use the %~1 style syntax - found no form of the %1 syntax which worked to preserve the caret
- Solution: Unquoted, use 4 consecutive carets (ex: use pass^^^^word to produce pass^word)
- 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).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
根据此页面,& | ( < > ^ 都是 Windows 批处理文件中的保留字符。 ^ 是转义字符,也是行继续字符。 ^^ 应该给你一个 ^,但是 ^ 可能需要转义。
要通过输入获得密码,您是否尝试过将插入符的数量增加四倍?
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?
主要问题是,当在一行中(引号之外)找到脱字符和其他特殊字符时,总是会对其进行处理。
%var%
扩展时也会解析内容,但!var!
延迟扩展时不会解析 示例
variabl 的内容为
-^" ^^-
,那就是set
行的问题。但是,当与
%var%
一起使用时,插入符号只能再次用作转义字符。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
The content of variabl is
-^"^^-
, that is the problem of theset
line.But the carets are only works as escape characters again, when using them with
%var%
.这解释了问题:
http://www.robvanderwoude.com/battech_inputvalidation_commandline.php
如果您处理批处理文件/CMD 脚本中的一些任意字符串,不要通过命令行参数传递它!相反,将它们放入一个文件中并让批处理文件读取它。因为命令行参数中的验证和清理从来都不是万无一失的。
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.
去掉引号可能会更容易。请参阅此 SO 链接 获取一些信息。
It might be easier to strip off the quotes. See this SO link for some info.
我有一个脚本将变量传递给另一个脚本。我不得不引用我的双引号:
问题(当发送到java加密时,胡萝卜被从密码中删除):
解决方案:
I had a script passing a variable to another script. I had to quote my double quotes:
Problem (carrot was removed from password when sent to be encrypted by java):
Solution: