用Java在bash路径中的空格 [英] Whitespace in bash path with java
问题描述
因此,我尝试导出文件变量:
So, I try to export file variable:
String somePath = "/Users/me/File with whitespaces.json";
Runtime runtime = Runtime.getRuntime();
runtime.exec(String.format("$MY_FILEPATH=\"%s\"", somePath));
我在这一行上遇到了一些异常:
And I get some exception on this line:
java.io.IOException: Cannot run program "$MY_FILEPATH=/Users/me/File": error=2, No such file or directory
P.S.如果我尝试在文件名中用\前缀空格",则会得到:
P.S. If I try "prepend space in file name with \", I get:
String somePath = "/Users/me/File\ with\ whitespaces.json";
Runtime runtime = Runtime.getRuntime();
runtime.exec(String.format("open %s", somePath));
在这一行上,我也得到了一些例外:
And I also get some exception on this line:
The files /Users/me/File\, with\, whitespaces.json do not exist.
P.P.S如果我将路径包裹在"中,也会出现类似上面的异常
P.P.S If I wrap path in "", I also get exception like above
推荐答案
添加:大多为 Runtime.exec
不是shell
Runtime.exec
is not a shell
- 使用
String
标记的Runtime.exec
重载在空格处.时期.Shell默认情况下会在空白处标记化,但是可以用引号或反斜杠替代.在Runtime.exec
中,它不能.如果您需要任何其他标记化,则必须使用采用String []
的重载.这回答了您实际提出的问题.例如,您可以通过以下方式执行open'带空格的路径'
:
- The overloads of
Runtime.exec
that take aString
tokenize at whitespace. Period. A shell tokenizes at whitespace by default but this can be overridden with quotes or backslash; inRuntime.exec
it cannot. If you want any other tokenization you have to use the overloads that takeString[]
instead. This answers the question you actually asked. For example you could do the equivalent ofopen 'path with spaces'
by:
Process p = runtime.exec (new String[] {"open", "path with spaces"});
-
Runtime.exec
仅运行程序.Shell命令经常运行一个程序,但并不总是运行.export
是一个内置的Shell,可以执行该外壳程序,但不是程序,因此Runtime.exec
不能.
Runtime.exec
runs programs only. Shell commands often run a program but not always.export
is a shell builtin that the shell executes but is not a program soRuntime.exec
cannot.
Runtime.exec
在子进程中运行程序,而 就像一个外壳.即使您可以某种方式将 export
作为子进程运行,它所做的更改也将仅在该子进程中存在.它不会影响Java进程或从Java进程运行的任何其他程序,就像您在子进程中使用shell进行 export
一样,最简单的是使用诸如(export foo = bar; echo $ foo);echo $ foo
-然后仅在子shell进程中设置,而不在父shell中设置,而不在父shell的其他任何子对象中设置.
Runtime.exec
runs programs in child processes, which is like a shell. Even if you could somehow run export
as a child process, the change it makes would exist only in that child process. It would NOT affect the Java process or any other programs run from the Java process, just like if you use shell to do export
in a child process -- most simply a subshell using parentheses like ( export foo=bar; echo $foo ); echo $foo
-- then it is set only in the child shell process and not the parent shell, and not any other children of the parent shell.
因此,如果您的目标是设置环境变量以供其他某些程序使用,则不能通过在 Runtime中运行任何来做到这一点.exec
.您可以通过使用 envp <的重载,传递经过修改的环境,以将环境变量添加(或更改或删除)到使用
Runtime.exec
运行的其他(真实)程序中./code>参数-请参见 javadoc -或使用 environment()
方法
Thus if your goal is to set an environment variable to be used by some other program(s), you cannot do that by running anything in Runtime.exec
. You can pass an environment that is modified to add (or change or delete) environment variables to some other (real) program you run with Runtime.exec
by using the overloads that take an envp
parameter -- see the javadoc -- or with ProcessBuilder
by using the environment()
method (javadoc)
但是,如果您的目标是做等效于shell的 foo ='带空格的路径';打开"$ foo"
(注释引号是必需的,这样才能在shell中工作).将 $ foo
替换为 path中的空格
(在令牌内,并因此作为参数传递)是通过 shell 完成的,而不是通过 open
程序-和 Runtime.exec
不是shell,因此不会执行此操作.如上第1点所述,您必须自己传递带有空格符号的 path
标记/参数,或显式运行shell(通常为/bin/sh
或仅 sh
),然后为 shell 提供 foo = ...;... $ foo ...
命令来执行-不需要 export
,因为该变量仅在外壳程序中使用,而不在子进程中使用.
But if your goal is to do the equivalent of shell's foo='path with spaces'; open "$foo"
(note quotes are needed for this to work in shell) you can't. The substitution of $foo
to path with spaces
(within a token, and thus passed as an argument) is done by the shell not by the open
program -- and Runtime.exec
is not a shell so it doesn't do this. You have to pass the path with spaces
token/argument yourself as in point 1 above, or explicitly run a shell (commonly /bin/sh
or just sh
) and give the shell the foo=...; ...$foo...
commands to execute -- and export
isn't needed since the variable is used only in the shell not the child process.
顺便说一句,即使在外壳中,当您设置环境变量或外壳变量时,也不会使用 $
,仅当您使用变量(或某些其他内容,例如命令替换或算术表达式)的值.
BTW even in shell you don't use a $
when you set an environment variable or shell variable, only when you use the value of a variable (or of certain other things like a command substitution or arithmetic expression).
这篇关于用Java在bash路径中的空格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!