从命令行运行时,JVM变量逃逸等号

4

运行Java应用程序,例如

java -Dme.unroll.url=unroll.me?param=val -jar my.jar
< p >在< code >param=val中,< code >=需要转义吗?这在谷歌上搜索起来非常困难,因为大多数结果都是关于转义Unix shell特殊字符的。在shell中,=不是特殊字符,所以不需要转义。

-Dme.unroll.url='unroll.me?param=val'

是否需要在此上下文中转义=,如果是,应该如何转义?


2
? 需要转义,这样 shell 才不会将其解释为通配符。 - devnull
当你不进行转义时,是否出现了奇怪的结果? - Sotirios Delimanolis
@SotiriosDelimanolis 即将运行它... 我还是发布了这个问题,因为即使在我的尝试中它能够工作,但这仍然可能是不良实践。 - djechlin
当我在Mac上尝试使用简单的“name=value”时,没有遇到任何问题。我想不出你会有任何原因。但是,我没有在其中包含“?”。 - Sotirios Delimanolis
@SotiriosDelimanolis 好吧,我知道 ? 需要 unix 级别的转义。我也找不到相关文档,这也是我在这里发布的另一个原因。 - djechlin
1个回答

4
我能找到的最规范的参考资料是Oracle java man page,其中提到:

-Dproperty=value

设置系统属性值。property变量是一个没有空格的字符串,表示属性的名称。value变量是表示属性值的字符串。如果value是一个带有空格的字符串,则用引号括起来(例如-Dfoo="foo bar")。

由于它提到了空格但没有提到=,我理解为不需要对=进行转义。这有些令人不满意,所以我决定看看OpenJDK的做法。作为广泛使用的参考实现,它的行为设定了一个实际标准。
至少在OpenJDK/HotSpot 8中,解析-D选项时,第一个=后的所有字符都被视为值的一部分,因此后续出现的=不需要(也不应该)进行转义。请参见源代码,相关部分如下:
bool Arguments::add_property(const char* prop) {
  const char* eq = strchr(prop, '=');
  char* key;
  // ns must be static--its address may be stored in a SystemProperty object.
  const static char ns[1] = {0};
  char* value = (char *)ns;

  size_t key_len = (eq == NULL) ? strlen(prop) : (eq - prop);
  key = AllocateHeap(key_len + 1, mtInternal);
  strncpy(key, prop, key_len);
  key[key_len] = '\0';

  if (eq != NULL) {
    size_t value_len = strlen(prop) - key_len - 1;
    value = AllocateHeap(value_len + 1, mtInternal);
    strncpy(value, &prop[key_len + 1], value_len + 1);
  }

调用 strchr 函数找到第一个 =,这被视为键和值之间的分隔符。
代码的其他部分在 VM 启动过程中寻找特定的属性参数,但我找到的所有地方都没有对 = 进行任何特殊处理。例如,Java 启动器 既设置又检查一些属性参数,但不转义或取消转义 =

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接