我应该如何将密码(包含特殊字符)作为命令行参数传递?
Posted
技术标签:
【中文标题】我应该如何将密码(包含特殊字符)作为命令行参数传递?【英文标题】:How should i pass the password(containing special chars) as commandline argument? 【发布时间】:2014-07-09 14:41:17 【问题描述】:我有一个部署脚本,我必须将 LDAP 密码作为 cmd 参数传递给该脚本。
实际密码: foo\$ser"ver\\ 1
(包含三个空格字符:开头、1
之前和1
之后)
例如
...bin>deployment.bat LDAPPassword= foo\$ser\"ver\\ 1
注意:密码中有空格如开头所示。
deployment.bat
调用一个类,将上述参数作为参数传递给该类。
问题是该类接收 2 个不同的参数:
args[0]= foo\$ser"ver\\ //The space after \\ is omitted
args[1]=1 //The space before and after 1 is omitted
我如何传递此密码以便将其作为单个字符串接收?
我已经尝试将密码引用为
...bin>deployment.bat LDAPPassword=" foo\$ser"ver\\ 1 "
但它不会起作用。
【问题讨论】:
请提供代码以获取更多信息 也许您可以详细说明deployment.bat
内部发生了什么,特别是如何处理参数并将其传递给您提到的类。另外,我已经编辑了您的帖子以尝试使您的问题更清楚,请查看并随时根据需要编辑/回滚。
尝试将空格替换为%20
,看看是否有效。在为 SAP 运行远程脚本和 bat 文件时,它适用于我。
【参考方案1】:
" foo\$ser\"ver\ 1 "
要引用完整的字符串,您需要对引号进行转义,这样它就不会被视为结束引号。
如果引号已经带有反斜杠前缀,那么您还必须转义反斜杠。所以密码为
this isa\"test
应该写成
"thisisa\\\"test"
如需更多信息,this 是 Windows 中解析参数的“常用”方式。
已编辑 - 只是为了记录测试。使用这个批处理文件 (test.cmd
)
@echo off
cls
echo(--------------------------------------------
echo [%1][%2][%3][%4][%5][%6][%7][%8][%9]
echo(--------------------------------------------
cmdline.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
echo(--------------------------------------------
cmdline.exe %*
echo(--------------------------------------------
java CmdLine %1 %2 %3 %4 %5 %6 %7 %8 %9
echo(--------------------------------------------
java CmdLine %*
echo(--------------------------------------------
cmdline.exe
是从这个 c 代码中获得的
#include "windows.h"
#include "stdio.h"
void main(int argc, char **argv)
int i;
printf("cmdline:[%s]\r\n\r\n",GetCommandLine());
for(i = 0; i < argc ; i++) printf("arg_%03d:[%s]\r\n",i,argv[i]);
;
CmdLine.java 是
public class CmdLine
public static void main (String[] args)
int i = 0;
for (String s: args)
System.out.println(String.format("arg_%03d:[%s]",++i,s));
运行test.cmd " foo\$ser\"ver\ 1 "
结果是
--------------------------------------------
[" foo\$ser\"ver\][1]["][][][][][][]
--------------------------------------------
cmdline:[cmdline.exe " foo\$ser\"ver\ 1 " ]
arg_000:[cmdline.exe]
arg_001:[ foo\$ser"ver\ 1 ]
--------------------------------------------
cmdline:[cmdline.exe " foo\$ser\"ver\ 1 "]
arg_000:[cmdline.exe]
arg_001:[ foo\$ser"ver\ 1 ]
--------------------------------------------
arg_001:[ foo\$ser"ver\ 1 ]
--------------------------------------------
arg_001:[ foo\$ser"ver\ 1 ]
--------------------------------------------
【讨论】:
... this is the "usual" way of parsing arguments in windows
但不适用于批处理文件。反斜杠不需要任何转义
@jeb,不是批量的。但问题是在最终程序(被调用的类,如 OP 状态)中获取指示的密码,将其作为参数传递给批处理文件。批处理文件看到什么并不重要,问题是将命令行值传输到此类中需要什么,并且该类看到正确的值。而正是程序的参数解析器需要对字符进行不同的转义。
好吧,你是对的,我将问题简化为只将密码传输到批处理文件而不是最终程序【参考方案2】:
您无法以任何方式逃避密码。 由于引号和空格的某些组合不能放在一个参数中。
像这样"
(<space><quote><space>
) 即使你在周围添加一些引号,也是不可能的,即使你引用了空格和引号本身。
myBat "
myBat " " "
myBat ^ "
myBat ^"^ ^"^ ^"
最好将密码中的所有引号都加双引号并将密码括在引号中。 然后你可以使用所有其他字符没有任何问题。
deployment.bat " foo\$ser\""ver\ 1 "
在deployment.bat中
@echo off
setlocal DisableDelayedExpansion
set "pwd=%~1"
setlocal EnableDelayedExpansion
set "pwd=!pwd:""="!"
echo pwd='!pwd!'
您应该只使用延迟扩展的密码以避免特殊字符出现问题。
要访问命令行参数,您还可以查看SO: How to receive even the strangest command line parameters?
【讨论】:
以上是关于我应该如何将密码(包含特殊字符)作为命令行参数传递?的主要内容,如果未能解决你的问题,请参考以下文章
Shell特殊变量:$0, $#, $*, $@, $?, $$和命令行参数
Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数