繁体   English   中英

Java Runtime.getRuntime()。exec(cmd)命令包含单引号

[英]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),并且命令未执行成功,经过一些调试后,似乎问题是由单引号引起的

所以,我的问题是

  1. 我可以使用java来执行一个带有单引号的shell命令(请注意,单引号位于参数的中间,而不是开始/结束)?
  2. 我可以使用shell命令在一个命令中rsync几个文件,并且命令中没有单引号(双引号)吗?

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM