Runtime.exec不起作用。

4

我正在尝试运行以下代码来交换文件名。我使用 Runtime.exec。代码抛出了IOException。有什么方法可以解决这个问题吗?

try {
Runtime.getRuntime().exec("file1=" + folderpath + " && file2=/mnt/sdcard/fsimages && temp=\"$(/system/xbin/mktemp -dp /mnt/sdcard)\" && /system/xbin/mv \"$file1\" $temp && /system/xbin/mv \"$file2\" \"$file1\" && /system/xbin/mv $temp/\"$file1\" \"$file2\"");
} catch (IOException e) {
    e.printStackTrace();
    return;
}

错误信息如下:

02-28 07:48:02.936: W/System.err(14399): java.io.IOException: Error running exec(). Command: [file1=/mnt/sdcard/fsimages_3, &&, file2=/mnt/sdcard/fsimages, &&, temp="$(/system/xbin/mktemp, -dp, /mnt/sdcard)", &&, /system/xbin/mv, "$file1", $temp, &&, /system/xbin/mv, "$file2", "$file1", &&, /system/xbin/mv, $temp/"$file1", "$file2"] 工作目录: null 环境变量: null

看起来像是Runtime.exec在每个&&前后插入了一个逗号。似乎问题出在Runtime.exec解释&&的方式上。为什么会这样? 如何防止这种情况发生?

2个回答

14

如果您使用 Runtime.exec(String) 方法,这个字符串会被视为一个命令及其参数,并在空格边界处粗略地分成子字符串。这种分割是该重载的标准行为(请参阅JavaDoc)。

Runtime.exec(...) 需要一个本机命令及其参数。您提供的是一行 shell 输入。exec 方法不理解 shell 输入,也不知道如何正确执行它。而且粗糙的分割(见上文)会把一切都搞砸。

如果您需要这样做,请使用以下方法:

String yourShellInput = "echo hi && echo ho";  // or whatever ... 
String[] commandAndArgs = new String[]{ "/bin/sh", "-c", yourShellInput };
Runtime.getRuntime().exec(commandAndArgs);

这相当于运行:

$ /bin/sh -c "echo hi && echo ho".
如果没有将sh安装在/bin/sh路径下,需要使用其所在的路径。

4

首先,问题并不是你所想象的那样,"看起来Runtime.exec在每个&&前后插入了逗号"实际上,错误报告显示您在Runtime.exec()中作为字符串数组(String[])给出的命令。这是Java Runtime.exec()方法的标准行为。

02-28 07:48:02.936: 
W/System.err(14399): java.io.IOException: 
Error runningexec(). Command: 
[file1=/mnt/sdcard/fsimages_3, &&, file2=/mnt/sdcard/fsimages, &&, temp="$(/system/xbin/mktemp, -dp, /mnt/sdcard)", &&, /system/xbin/mv, "$file1", $temp, &&, /system/xbin/mv, "$file2", "$file1", &&, /system/xbin/mv, $temp/"$file1", "$file2"] 
Working Directory: null Environment: null

您可以从错误中看到Java是如何解释您硬编码的命令的,返回的字符串数组向您展示了"file1=/mnt/sdcard/fsimages_3"被视为打开命令来执行,而其余部分" &&""file2=/mnt/sdcard/fsimages"等则被视为参数。

我认为您应该首先尝试将您的命令拆分成类似于数组的结构。以下是一个示例:

Process process;
String[] commandAndArgs = new String[]{ "/bin/sh", "mv", "/mnt/sdcard/fsimages_3","/mnt/sdcard/fsimages" };
process = Runtime.getRuntime().exec(commandAndArgs);

接下来,你的错误显示你的工作目录为空,而且你的环境也为空。因此,你需要为进程设置它们两个。从Java文档中可以看到,它说明了这个exec()重载方法。

exec(String[] cmdarray, String[] envp, File dir)

执行指定的命令和参数,使用指定的环境和工作目录在单独的进程中运行。

如果以上方法都无效,请编写一个 shell 脚本文件并设置其可执行权限,以便执行您的命令。

chmod 755 or chmod +x script.sh;

然后尝试运行它。我希望它能像我的情况一样,脚本文件的方法能够奏效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接