为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

有只小跳蛙 2023-03-23 15:23:44
我尝试从 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 中将上述命令作为单个字符串调用?
查看完整描述

2 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

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 库。


查看完整回答
反对 回复 2023-03-23
?
PIPIONE

TA贡献1829条经验 获得超9个赞

根据文档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 - 包含要调用的命令及其参数的数组。


查看完整回答
反对 回复 2023-03-23
  • 2 回答
  • 0 关注
  • 267 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号