使用带空格的参数调用 java.lang.Runtime.exec(String) 时出现问题

我尝试从 Java 进程中的特定位置调用带有文件的 vim 编辑器:

Runtime.getRuntime().exec("gvim /etc/fstab '+normal GW'");

不幸的是,这不起作用。它给出了一条来自 gvim 的奇怪错误消息,这无助于发现问题 ("/etc/fstab" "/etc/fstab" [readonly] 12L, 664C)。

直接输入终端的相同命令效果很好。

我试图修改命令:

Runtime.getRuntime().exec("gvim /etc/fstab +normal\ GW");

直接在终端中输入时也可以使用。但这给出了完全相同的行为。

什么工作是将命令及其参数拆分为 String[]:

Runtime.getRuntime().exec(new String[]{"gvim", "/etc/fstab" ,"+normal GW"});

这种行为的原因是什么?如何从 Java 中将上述命令作为单个字符串调用?


有只小跳蛙
浏览 268回答 2
2回答

慕森王

exec不是一个完整的外壳。为方便起见,它确实允许您传递带有可执行文件名称和参数的单个字符串(与使用版本相反String[]),但它用于拆分该字符串的逻辑非常简单,它只是调用new StringTokenizer(command),它只是拆分为空格,并且不了解完整命令 shell 会提供的特殊引用和转义行为。所以你的单引号没有被尊重。gvim /etc/fstab '+normal GW'   // last quoted section supposed to be a single arg成为String[]{ "gvim", "/etc/fstab", "'+normal", "GW'" } // four args instead of three如何从 Java 中将上述命令作为单个字符串调用?你真的需要这个吗?除非应用程序动态地接受来自交互式用户的命令行输入,否则应该可以在编写程序时拆分参数。那样安全多了。如果你真的需要这个,你可以将整个字符串传递给命令 shell。尝试 Runtime.getRuntime().exec(new String[]{"bash", "-c", theCommand });但是涉及一些开销。除此之外,您可以尝试找到一个可以“正确”拆分字符串的 Java 库。

PIPIONE

根据文档exec(String command)将整个字符串视为命令,如果我们查看文档public Process exec(String command)          throws IOException在单独的进程中执行指定的字符串命令。这是一个方便的方法。exec(command) 形式的调用与调用 exec(command, null, null) 的行为方式完全相同。参数:command - 指定的系统命令。来到exec(String[] cmdarray)它会将 cmdarray 视为包含要调用的命令及其参数的数组。这是这两种方法之间的唯一区别,这可能是问题所在public Process exec(String[] cmdarray)          throws IOException在单独的进程中执行指定的命令和参数。这是一个方便的方法。exec(cmdarray) 形式的调用与调用 exec(cmdarray, null, null) 的行为方式完全相同。参数:cmdarray - 包含要调用的命令及其参数的数组。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java