为什么在 bash(MacOS)中使用 expr 会出现语法错误?

Why do I get a syntax error when using expr in bash(MacOS)?

我刚开始学习shell,当我在这个简单的代码中遇到语法错误时,我感到非常困惑:

str="Hello world!"
echo $(expr length "$str")

但这段代码实际上可以在 Ubantu 上运行。是因为我的 bash 版本过时了吗?还是MacOS系统的问题?

我已经更新了我的bash版本,现在是GNU bash 5.1.16,但是这个问题仍然存在。我现在真的很迷茫。

Mac 上的

exprOS 不接受参数 length。手册页包含这个相当倾斜的段落:

According to the POSIX standard, the use of string arguments length, substr, index, or match produces undefined results. In this version of expr, these arguments are treated just as their respective string values.

换句话说,expr length 只是 returns lengthexpr length "$str" 是一个语法错误,因为 expr 只接受一个参数。

这真的不是问题,因为 Bash 脚本基本上根本不需要使用 expr。 Bash 有 built-in 设施,这些设施或多或少地取代了所有遗留的 expr 逻辑。

要获取 Bash 中字符串的长度,请尝试

${#str}

更多,可能从Bash中的parameter expansions开始。

expr 是一个 OS 实用程序,它独立于您的 shell,因此您使用哪个版本的 Bash 并没有什么区别,或者实际上您是否使用 shell。

如果您发现自己处于需要在 POSIX sh / Bourne shell 脚本中可移植地获取字符串长度的情况,也许求助于 Awk。

len=$(printf '%s\n' "$str" | awk '{ print(length([=11=])) }')

(如果 str 包含多行,这将打印多个数字。如果您需要查找包含换行符的字符串的总长度,则不难更改它,但我猜我们不会不需要去那里。)