使用 Java 的 Runtime.getRuntime().exec() 进行 Rsync,命令中有双引号。

huangapple go评论71阅读模式
英文:

Rsync using java Runtime.getRuntime().exec() with double qoute in command

问题

你好我正在尝试执行以下操作

    Process p = null;
    StringBuffer rbCmd = new StringBuffer();
    
    rbCmd.append("rsync -e \"ssh -i /root/.ssh/key\" -va --relative /home/lego/hyb/abc/PVR2/Testdata/./R887/SCM/System root@myMachine:/xyz/data/SCMdata/");
    
    p = Runtime.getRuntime().exec(rbCmd.toString());

但是我在命令行上得到以下错误该命令在命令行上可以正确执行

Missing trailing-" in remote-shell command. 
rsync error: syntax or usage error (code 1) at main.c(361) [sender=3.0.6]  

问题出在命令中引用ssh密钥的双引号

请协助进行更正
英文:

Hello I am trying to execute following :

Process p = null;
StringBuffer rbCmd = new StringBuffer();

rbCmd.append("rsync -e \"ssh -i /root/.ssh/key\" -va --relative /home/lego/hyb/abc/PVR2/Testdata/./R887/SCM/System root@myMachine:/xyz/data/SCMdata/");

p = Runtime.getRuntime().exec(rbCmd.toString());

But I am getting following error on command line.Command executes correctly on command line

Missing trailing-" in remote-shell command.
rsync error: syntax or usage error (code 1) at main.c(361) [sender=3.0.6]

Issue is because of double quotes inside the command where I mention ssh key.

Please help with correction.

答案1

得分: 1

你的方法行不通,因为Runtime.exec()无法意识到“ssh -i /root/.ssh/key”是传递给rsync的单个参数。转义双引号可以让编译器满意,但无法解决根本问题,即内置分词器的限制。

也许尝试类似这样的方法会更成功:

Process p = Runtime.getRuntime().exec
    (new String[]{"rsync", "-e", "ssh -i /root/.ssh/key", "-va", "--relative", ... });

也就是说,你自己对命令行进行分词,然后将各个标记形成String[]。你提前确定了传递给rsync的参数,而不是让exec()(错误地)去理解。

不要忘记,如果rsync产生任何输出,你需要安排你的应用程序来消耗它的stdoutstderr,否则可能会造成阻塞。

英文:

Your approach won't work because Runtime.exec() does not realize that "ssh -i /root/.ssh/key" is a single argument to rsync. Escaping the double-quotes keeps the compiler happy, but doesn't remove the fundamental problem, which is the limits of the built-in tokenizer.

You might have more luck with something like this:

Process p = Runtime.getRuntime().exec
    (new String[]{"rsync", "-e", "ssh -i /root/.ssh/key", "-va" "--relative" ... });

That is, tokenize the command line yourself, and form the individual tokens into a String[]. You're deciding in advance what the arguments to rsync are, rather than allowing exec() to figure it out (wrongly).

Don't forget that if rsync produces any output, you'll need to arrange for your application to consume its stdout and stderr, or it could stall.

huangapple
  • 本文由 发表于 2020年9月9日 19:54:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63811140.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定