我应该如何将密码(包含特殊字符)作为命令行参数传递?

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】:

您无法以任何方式逃避密码。 由于引号和空格的某些组合不能放在一个参数中。

像这样" (&lt;space&gt;&lt;quote&gt;&lt;space&gt;) 即使你在周围添加一些引号,也是不可能的,即使你引用了空格和引号本身。

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, $#, $*, $@, $?, $$和命令行参数

linux Shell特殊变量 $0, $#, $*, $@, $?, $$和命令行参数

如何转义任意字符串以用作 Bash 中的命令行参数?