shell脚本中wildcharacter *的奇怪行为

时间:2013-02-27 07:24:55

标签: bash shell echo wildcard zsh

在我的shell脚本中,我有以下代码

echo * | tr ' ' '\n'

在这里,我注意到虽然我使用的是*,但它正在跳过隐藏文件(。*) 之后我尝试了一个明显的改变

echo .* | tr ' ' '\n'

这解决了我的隐藏文件问题。但我只是对*

这种奇怪的行为感到好奇

因为。*是*
的子集

的理想输出
  1. echo * - >所有文件包括隐藏文件

  2. echo。* - >所有隐藏文件

  3. echo [^。] * - >所有非隐藏文件(当前为echo *)

  4. 因此echo *表现得像echo [^。] *

    如何使用echo获取包含隐藏文件的整个文件列表。类似的是ls和dir的输出,尽管ls -a给出了理想的输出

2 个答案:

答案 0 :(得分:6)

shell glob *被定义为忽略隐藏文件,因此按预期工作。 .*会将扩展为隐藏文件。

有些shell允许通过选项更改此行为。例如。 zsh默认情况下允许setopt dotglob变为不符合(对POSIX)以及glob dotfiles。对于bash,您可以使用shopt -s dotglob。但要注意脚本可能会出现故障,因为它们通常会假定用于globbing的POSIX行为。

获取所有文件的最佳选择是不使用带有globbing的echo,但是例如find . -maxdepth 1(如果你对echo非常不满意,也许echo * .*会这样做,但是如果有的话glob与任何文件都不匹配,在这种情况下可以保留glob模式。

答案 1 :(得分:3)

Filename Expansion

中介绍了这一点
  

当模式用于文件名扩展时,除非设置了shell选项dotglob,否则必须明确匹配文件名开头或紧跟斜杠后面的字符“。”。匹配文件名时,必须始终明确匹配斜杠字符。在其他情况下,'。'字符不会被特别处理。

如果您想将.**一起包含,则必须同时提供两个参数来回显

echo .* * | tr ' ' '\n'

或使用dotglob

shopt -s dotglob
echo * | tr ' ' '\n'

但仍然排除了...