bash - 为什么 bash 在数组的前面吞下 -e

标签 bash

<分区>

给定以下语法:

x=(-a 2);echo "${x[@]}";x=(-e 2 -e); echo "${x[@]}"

输出:

-a 2
2 -e

期望的输出

-a 2
-e 2 -e

为什么会这样?我该如何解决?

最佳答案

tl;dr

printf "%s\n" "${x[*]}"

解释

echo 有 3 个选项:

$ help echo
[…]
Options:
  -n    do not append a newline
  -e    enable interpretation of the following backslash escapes
  -E    explicitly suppress interpretation of backslash escapes

所以如果你运行:

$ echo -n
$ echo -n -e
$ echo -n -e -E

你什么也得不到。即使您将每个选项都放在引号中,它在 bash 中看起来仍然是一样的:

$ echo "-n"
$ echo "-n" "-e"

最后一个命令使用两个参数运行 echo:-n-e。现在将其与:

$ echo "-n -e"
-n -e

我们所做的是使用单个参数运行echo:-n -e。由于 bash 不识别(组合的)选项 -n -e,它最终像我们想要的那样将单个参数回显到终端。

应用于数组

在第二种情况下,数组x 以元素-e 开头。在 bash 展开数组 ${x[@]} 之后,您实际上正在运行:

$ echo "-e" "2" "-e"
2 -e

因为第一个参数是 -e,它被解释为一个选项(而不是回显到终端),正如我们已经看到的那样。

现在将其与另一种数组扩展方式 ${x[*]} 进行对比,后者有效地执行以下操作:

$ echo "-e 2 -e"
-e 2 -e

bash 看到单个参数 -e 2 -e — 由于它不将其识别为一个选项 — 它会将参数回显到终端。

请注意,${x[*]} 样式扩展通常不安全。举个例子:

$ x=(-e)
$ echo "${x[*]}"

即使我们期望 -e 被回显,也没有打印任何内容。如果您一直在关注,您已经知道为什么会这样。

转义

解决方案是转义 echo 命令的任何参数。不幸的是,与其他提供某种方式说“嘿!以下参数不应被解释为选项”(通常是-- 参数),bash 没有为echo 提供这种转义机制。

幸运的是,printf 命令提供了 echo 所提供功能的超集。因此我们得出了解决方案:

printf "%s\n" "${x[*]}"

关于bash - 为什么 bash 在数组的前面吞下 -e,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21150793/

相关文章:

linux - 安装后脚本 : OpenSSH fails

regex - 使用 sed 失败解析 shebang

bash - 在 Makefile 中提取操作系统名称和版本号

linux - rdiff-backup bash 脚本和 cron 问题

c - 无法将 '#' 字符作为命令行参数传递

arrays - 用冒号分割字符串

Bash 根据 split 命令计算字母后缀(即带有字母的 26 进制整数)

regex - 与 awk 一起使用的正则表达式中的量词表现出意外

bash - 使用 bash 脚本从 plist 中提取字符串,也许是 sed?

linux - 使用 BASH 脚本检查 txt 文件中的预测值