为什么在 Java 中使用管道执行系统命令会在没有空格的情况下失败?

Why executing system command with pipeline in Java fail without whitespaces?

在 shell 命令行中,两个命令都是合法的并且 运行 没有问题:

# without whitespaces
parted /dev/sdd print free -m|grep free

# with whitespaces
parted /dev/sdd print free -m | grep free

但是,一旦我从 Java 它的前一个版本(没有空格的那个)运行,即:

Runtime.getRuntime().exec("parted /dev/sdd print free -m|grep free")

失败:

2019-09-10 18:33:34.012  WARN 2528 --- [           main] Utils      : Error running parted /dev/sdd print free -m|grep free: parted: invalid option -- '|'
parted: invalid option -- 'g'
parted: invalid option -- 'r'
parted: invalid option -- 'e'
parted: invalid option -- 'p'
Usage: parted [-hlmsv] [-a<align>] [DEVICE [COMMAND [PARAMETERS]]...]

然而,与后一个命令版本(带空格的那个)相同的 java 行 运行 完全没问题。
显然,当 Java 中的 运行 时,'|' 符号无法被识别。问题是为什么?

Java exec 函数使用的规则不是 shell.

使用的规则

exec splits into tokens based on whitespace.

因此foo|bar是一个单一的标记。 相比之下,Shell 解析会将其视为 3 个独立的元素,foo|bar。 bash 的手册页为您详细说明了 bash 处理过程。