所以,我尝试导出文件变量:
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
P.S。 如果我尝试使用\"在文件名中添加空格,我得到:
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 如果我在""中包装路径,我也会像上面那样得到例外
答案 0 :(得分:1)
添加:主要是欺骗Why does Runtime.exec(String) work for some but not all commands?
Runtime.exec
不是shell
Runtime.exec
在空白处采用String
标记化的重载。期。默认情况下,shell会在空白处进行标记,但这可以用引号或反斜杠覆盖;在Runtime.exec
它不能。如果您想要任何其他标记化,则必须使用String[]
代替的重载。这回答了你实际问的问题。例如,您可以通过以下方式执行open 'path with spaces'
的等效操作:Process p = runtime.exec (new String[] {"open", "path with spaces"});
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的任何其他子进程。
因此,如果您的目标是设置一个环境变量以供其他某些程序使用,则不能通过在{{1}中运行任何来实现这一点}。您可以通过使用带有Runtime.exec
参数的重载来传递一个被修改的环境,以便将环境变量添加(或更改或删除)到您使用Runtime.exec
运行的其他(实际)程序 - 请参阅{使用envp
方法the javadoc
ProcessBuilder
但是,如果您的目标是执行相同的shell environment()
(需要注意引号才能在shell中工作),那么您就无法做到。将foo='path with spaces'; open "$foo"
替换为$foo
(在令牌中,因此作为参数传递)由shell 而不是path with spaces
程序完成 - open
不是shell,所以它不会这样做。您必须自己传递Runtime.exec
令牌/参数,如上面第1点所述,或者显式运行shell(通常为path with spaces
或仅/bin/sh
)并提供 shell 要执行的sh
命令 - 并且不需要foo=...; ...$foo...
,因为变量仅用于shell而不是子进程。
BTW即使在shell中,当你设置环境变量或shell变量时,你也不会使用export
,只有当你使用值时一个变量(或某些其他东西,如命令替换或算术表达式)。