用Java在bash路径中的空格 [英] Whitespace in bash path with java

查看:56
本文介绍了用Java在bash路径中的空格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我尝试导出文件变量:

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

  1. 使用 String 标记的 Runtime.exec 重载在空格处.时期.Shell默认情况下会在空白处标记化,但是可以用引号或反斜杠替代.在 Runtime.exec 中,它不能.如果您需要任何其他标记化,则必须使用采用 String [] 的重载.这回答了您实际提出的问题.例如,您可以通过以下方式执行 open'带空格的路径':
  1. The overloads of Runtime.exec that take a String tokenize at whitespace. Period. A shell tokenizes at whitespace by default but this can be overridden with quotes or backslash; in Runtime.exec it cannot. If you want any other tokenization you have to use the overloads that take String[] instead. This answers the question you actually asked. For example you could do the equivalent of open 'path with spaces' by:


    Process p = runtime.exec (new String[] {"open", "path with spaces"});

  1. Runtime.exec 仅运行程序.Shell命令经常运行一个程序,但并不总是运行. export 是一个内置的Shell,可以执行该外壳程序,但不是程序,因此 Runtime.exec 不能.

  1. 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 so Runtime.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆