plinkで特殊文字をエスケープするのではなく、cmdが特殊文字をどのように扱うかで問題が発生していることを認識しました。このために、私は、コマンドライン引数を取り、それを印刷するには、単純なJavaクラスを作成しました:
public class MyTest {
public static void main(String args[]) {
System.out.println(args[0]);
}
}
私は、このアプリケーションに特殊文字を入力を渡され、ここで出力されます:
C:\>java MyTest "[email protected]#$%^&*()_+{}|:"<>?-=`[]\;',./sss"
> was unexpected at this time.
C:\>java MyTest "[email protected]#$%^&*()_+{}|:\"<>?-=`[]\;',./sss"
> was unexpected at this time.
C:\>java MyTest "[email protected]#$%^&*()_+{}|:\"^<^>?-=`[]\;',./sss"
[email protected]#$%^&*()_+{}|:"<>?-=`[]\;',./sss
C:\>java MyTest "[email protected]#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasfafds"
[email protected]#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasfafds
C:\>java MyTest "[email protected]#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>afds"
[email protected]#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasf<>afds
C:\>java MyTest "[email protected]#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"ds"
[email protected]#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasf<>af"ds
C:\>java MyTest "[email protected]#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"dasd<>fs"
> was unexpected at this time.
C:\>java MyTest "[email protected]#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"dasd^<^>fs"
[email protected]#$%^&*()_+{}|:"<>?-=`[]\;',./s"sasf<>af"dasd<>fs
C:\>java MyTest "[email protected]<>#$%^&*()_+{}|:\"^<^>?-=`[]\;',./s\"sasf<>af\"dasd^<^>fs"
[email protected]<>#$%^&*()_+{}|:"<>?-=`[]\;',./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の処理方法は異なります。特殊文字はエスケープされ、プロセスに渡されます。したがって、それははるかに多くの問題を作成します。これを処理するために、私は上記のコードを変更:
Javaでは
commandtoexecute = ['plink.exe', '-ssh', '-batch', '-pw', password, username + '@' + ipaddress, command]
subprocess.Popen(commandtoexecute, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
、のように書くことができます
ここ
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でエスケープされていますが、渡された引数を見つけるのに役立ちました。
CMDが変数を渡していると思うので、cmdスクリプトでは%%%を使用することもできます。 その他の情報 - http://www.robvanderwoude.com/escapechars.php –