我正在使用plink
来ssh到许多服务器并执行命令。但是,当密码有特殊字符时,无法在控制台上执行命令。
用法:plink.exe -ssh -pw "password" user@myhost "command to execute"
apof~!@#$%^&*()_+{}|:"sdfsdfs!df
- 使用"
转发\
时取得成功。
apof~!@#<>$%^&*()_+{}|:"sdfsdfs!df
- 使用"
转发\
时取得成功。
apof~!@#$%^&*()_+{}|:"<>sdfsdfs!df
- 失败。使用"
转义\
。失败消息:&gt;这时出人意料。
apof~!@#$%^&*()_+{}|:"><sdfsdfs!df
- 失败。使用"
转义\
。失败消息:&lt;这时出人意料。
apof~!@#$%^&*()_+{}|:"<sdfsdfs!df
- 失败。使用"
转义\
。失败消息:系统找不到指定的路径。
apof~!@#$%^&*()_+{}|:">sdfsdfs!df
- 失败。使用"
转义\
。失败消息:系统找不到指定的路径。
在<
之后看起来>
或"
时,转义不起作用。很多我知道如何处理这个问题?
答案 0 :(得分:0)
意识到问题不在于使用plink来转义特殊字符,而是使用cmd如何处理特殊字符。为此,我创建了一个简单的Java类来获取命令行参数并打印它:
public class MyTest {
public static void main(String args[]) {
System.out.println(args[0]);
}
}
我将带有特殊字符的输入传递给此应用程序,这是输出:
C:\>java MyTest "apof~!@#$%^&*()_+{}|:"<>?-=`[]\;',./sss"
> was unexpected at this time.
C:\>java MyTest "apof~!@#$%^&*()_+{}|:\"<>?-=`[]\;',./sss"
> was unexpected at this time.
C:\>java MyTest "apof~!@#$%^&*()_+{}|:\"^<^>?-=`[]\;',./sss"
apof~!@#$%^&*()_+{}|:"<>?-=`[]\;',./sss
C:\>java MyTest "apof~!@#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasfafds"
apof~!@#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasfafds
C:\>java MyTest "apof~!@#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>afds"
apof~!@#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasf<>afds
C:\>java MyTest "apof~!@#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"ds"
apof~!@#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasf<>af"ds
C:\>java MyTest "apof~!@#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"dasd<>fs"
> was unexpected at this time.
C:\>java MyTest "apof~!@#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"dasd^<^>fs"
apof~!@#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasf<>af"dasd<>fs
C:\>java MyTest "apof~!@<>#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"dasd^<^>fs"
apof~!@<>#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasf<>af"dasd<>fs
根据此分析,我们发现,只有"
和才能转义的特殊字符<
或>
符号出现在"
之后还必须使用^
进行转义。 This document向我指出逃生部分。
下面是我为生成转义参数而编写的python函数:
def escapepassword(initpassword):
passsplit = list(initpassword)
quotesflag=False
index = -1
for token in passsplit:
index += 1
if quotesflag and (token in ("<", ">")):
passsplit[index] = "^" + token
else:
if token == '"':
passsplit[index] = "\\\""
quotesflag = not quotesflag
return "".join(passsplit)
我仍然遇到使用转义参数调用可执行文件的问题。我使用以下执行命令的方式:
subprocess.Popen('plink.exe -ssh -batch -pw' + escapepassword(password) + ' ' + username + '@' + ipaddress + ' "' + command + '"', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
或者用Java来说,它将是:
Runtime.getRuntime().exec("plink.exe -ssh -batch -pw" + escapepassword(password) + " " + username + "@" + ipaddress + " \"" + command + "\"");
这给了很多麻烦。 python或Java执行过程的方式是不同的。特殊字符被转义并传递给进程。因此,它会产生更多问题。为了解决这个问题,我将上面的代码更改为:
commandtoexecute = ['plink.exe', '-ssh', '-batch', '-pw', password, username + '@' + ipaddress, command]
subprocess.Popen(commandtoexecute, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
在Java中,可以写成:
Runtime.getRuntime().exec(new String [] {"plink.exe", "-ssh", "-batch", "-pw", password, username + "@" + ipaddress, command);
这里,命令之间有空格,例如ls -al
,但这是传递参数以启动进程的方法。当我尝试在"
之间传递命令时,它发出了错误,指出找不到命令,因为"
也被传递以在远程系统上执行。
注意:强>
我使用命令WMIC path win32_process get name,Commandline | find "plink.exe"
来查看命令行参数。输出是html转义的,但是,它有助于找到传递的参数。