[英]Java Runtime.getRuntime().exec(cmd) command contain single quote
我需要使用Java来使用一个命令rsync几个文件以下命令在shell中工作正常rsync -avrz --timeout = 100 rsync://10.149.21.211:8730 /'logflow / click / file1 logflow / click / file2'/家用/ kerrycai /车夫”
但是当我使用以下Java代码时,它不起作用
String cmd = "rsync -avrz --timeout=100 rsync://10.149.21.211:8730/'logflow/click/file1 logflow/click/file2' /home/kerrycai/puller";
Process p = Runtime.getRuntime().exec(cmd);
int ret = p.waitFor();
ret值不等于0(在我的测试中为5),并且命令未执行成功,经过一些调试后,似乎问题是由单引号引起的
所以,我的问题是
@Chris的注意事项:在一个参数中,这个多个文件名(真正被修改过的部分文件名)的组合确实非常不寻常,甚至对Unix来说都是“可疑的”,但对于rsync
,它是 (或者至少是)正确的。
前言:Java Runtime.exec
不会“执行shell命令”(除非你明确地运行shell并给它一个命令); 它运行一个带有参数的程序 。 这些不同的东西经常被混淆,因为普通用户使用的大多数shell命令都是运行程序的命令,但这是差异很重要的一种情况。 特别是引用一个空格到shell会导致shell将一个参数传递给包含空格的程序,而不是分成两个(或更多)参数,但引用本身不包含在参数中。
首先,您应该在高级使用情况下查看手册页(在您的系统上或在线访问https://download.samba.org/pub/rsync/rsync.html )。 当前(和IME甚至是中等旧版本)rsync有一个更方便的语法,带有单独的参数来获取多个文件 , Runtime.exec(String)
使用的简单解析可以像这样处理:
rsync -avrz --timeout=100 --port=8730 10.149.21.211::logflow/click/file1 ::logflow/click/file2 /home/kerrycai/puller
但是如果你需要(或者真的想)使用引用空间形式,那么你需要自己进行标记化并使用@EJP建议的String[]
重载 - 虽然你仍然可以使用Runtime
,但你不需要ProcessBuilder
为此。 具体做一些事情:
String[] cmdarray = {"rsync",
"-avrz",
"--timeout=100",
"rsync://10.149.21.211:8730/logflow/click/file1 logfile/click/file2",
// separated argument contains space but not single (or other) quote
"/home/kerrycai/puller" };
... Runtime.getRuntime.exec(cmdarray); ...
你从Java调用一个有点大的命令。 为什么不使用shell脚本? 将您的myScript.sh
命令放在myScript.sh
,然后让Java调用/bin/bash myScript.sh
。 使用Java中的字符串处理所带来的所有奇怪感都消失了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.