所以,我尝试导出文件变量:
String somePath = "/Users/me/File with whitespaces.json";
Runtime runtime = Runtime.getRuntime();
runtime.exec(String.format("$MY_FILEPATH=\"%s\"", somePath));
我在这行遇到了一些例外:
java.io.IOException: Cannot run program "$MY_FILEPATH=/Users/me/File": error=2, No such file or directory
附注 如果我尝试“在文件名中添加空格”,我得到:
String somePath = "/Users/me/File\ with\ whitespaces.json";
Runtime runtime = Runtime.getRuntime();
runtime.exec(String.format("open %s", somePath));
我在这条线上也遇到了一些例外:
The files /Users/me/File\, with\, whitespaces.json do not exist.
P.P.S 如果我将路径包裹在“”中,我也会得到像上面这样的异常
添加:主要是骗人的 为什么 Runtime.exec(String) 对某些命令有效,但不是对所有命令有效?
Runtime.exec
不是贝壳
Runtime.exec
的重载在空白处采用 String
标记。时期。默认情况下,shell 在空格处进行标记,但这可以用引号或反斜杠覆盖;在 Runtime.exec
中它不能。如果您想要任何其他标记化,则必须使用采用 String[]
的重载。这回答了您实际提出的问题。例如,您可以通过以下方式执行相当于 open 'path with spaces'
的操作:Process p = runtime.exec(new String[] {"open", "带空格的路径"});
Runtime.exec
仅运行程序。 Shell 命令经常运行程序,但并非总是如此。 export
是 shell 内置的 shell 执行工具,但它不是程序,因此 Runtime.exec
不能。Runtime.exec
在子进程中运行程序,这就像一个shell。即使您可以以某种方式将 export
作为子进程运行,它所做的更改也将仅存在于该子进程中。它不会影响 Java 进程或从 Java 进程运行的任何其他程序,就像您使用 shell 在子进程中执行 export
一样——最简单的是使用像 ( export foo=bar; echo $foo ); echo $foo
这样的括号的子 shell——然后它就被设置了仅在子 shell 进程中,而不是在父 shell 中,并且不在父 shell 的任何其他子进程中。因此,如果您的目标是设置一个环境变量以供其他程序使用,则无法通过在 Runtime.exec
中运行
anything来实现这一点。您可以通过使用采用
Runtime.exec
参数的重载来传递经过修改的环境,以将环境变量添加(或更改或删除)环境变量到您使用 envp
运行的其他(实际)程序 - 请参阅 javadoc - - 或者通过使用 ProcessBuilder
方法 (javadoc)来使用
environment()
但是,如果您的目标是执行与 shell 的
foo='path with spaces'; open "$foo"
相同的操作(请注意,需要使用引号才能在 shell 中工作),那么您就不能这样做。 $foo
到 path with spaces
的替换(在令牌内,因此作为参数传递)是由 shell 完成的,而不是由 open
程序完成的——并且
Runtime.exec
不是 shell,因此它不会不要这样做。您必须像上面第 1 点一样自行传递
path with spaces
标记/参数,或者显式运行 shell(通常是
/bin/sh
或只是
sh
)并向the shell 提供要执行的
foo=...; ...$foo...
命令——并且
export
不需要,因为该变量仅在 shell 中使用,而不是在子进程中使用。顺便说一句,即使在 shell 中,当您
设置
环境变量或 shell 变量时,也不会使用
$
,只有当您使用变量的值(或某些其他事物,如命令替换或算术表达式) )。