java bash 路径中的空格

问题描述 投票:0回答:1

所以,我尝试导出文件变量:

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 如果我将路径包裹在“”中,我也会得到像上面这样的异常

java bash command-line-interface whitespace
1个回答
2
投票

添加:主要是骗人的 为什么 Runtime.exec(String) 对某些命令有效,但不是对所有命令有效?

Runtime.exec
不是贝壳

  1. Runtime.exec
    的重载在空白处采用
    String
    标记。时期。默认情况下,shell 在空格处进行标记,但这可以用引号或反斜杠覆盖;在
    Runtime.exec
    中它不能。如果您想要任何其他标记化,则必须使用采用
    String[]
    的重载。这回答了您实际提出的问题。例如,您可以通过以下方式执行相当于
    open 'path with spaces'
    的操作:
 Process p = runtime.exec(new String[] {"open", "带空格的路径"});
  1. Runtime.exec
    仅运行程序。 Shell 命令经常运行程序,但并非总是如此。
    export
    是 shell 内置的 shell 执行工具,但它不是程序,因此
    Runtime.exec
    不能。

  2. 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 变量时,也不会使用
$,只有当您使用变量的值(或某些其他事物,如命令替换或算术表达式) )。

© www.soinside.com 2019 - 2024. All rights reserved.