将“*()”作为参数传递给 bash 中的程序

Passing "*()" as an argument to a program in bash

编辑 2:即使做 "ls *()" 也会导致 bash 不 return 并使用一个 cpu 的 100%。有谁知道为什么 bash 这样做?

我正在学习 C 并了解参数,并且想知道当作为参数传递时哪些字符会做奇怪的事情。我通过 bash 将不带引号的“*()”传递给 c 程序,例如:

$ ./program *()

无法使用 ctrl c 或 ctrl z 退出 Bash。当我查看 htop 时,它使用了 100% CPU 并且我不得不 SIGKILL 它。有谁知道这里发生了什么。我只是好奇。

编辑:即使是简单的程序

#include <stdio.h>
int main(int argc, char *argv[]){ return 0; }

导致此行为。

你可能会看到它用 strace -ppid 做了什么。重新启动后该行为是否可重现? Bash 当我在 CentOs 6.3 上尝试时出现语法错误。在我看来,您的系统中有些东西已损坏,但可能仅在 运行 内核中,也许在 proc table.

tn:11: cat program.c
#include <stdio.h>
int main(int argc, char *argv[]){ return 0; }
tn:12: gcc program.c
tn:13: ./a.out *()
bash: syntax error near unexpected token `('
tn:13: bash -version
GNU bash, version 4.1.2(1)-release (i386-redhat-linux-gnu)
tn:14: uname -a
Linux localhost.localdomain 2.6.32-279.11.1.el6.i686 #1 SMP Tue Oct 16 14:40:53 UTC
2012 i686 i686 i386 GNU/Linux
tn:15: cat  /etc/redhat-release 
CentOS release 6.3 (Final)
tn:16: gcc  --version
gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

这似乎是 bash 中的一个已知错误,已在版本 4.3.16 中修复。它仅在启用 extglob 功能时发生,例如,如果您有类似

的命令
shopt -s extglob

在您的 .bashrc 或其他初始化文件中。

我可以在 Linux Mint 17 上用 bash 4.3.11 一致地重现它:

$ bash --norc
bash-4.3$ mkdir empty
bash-4.3$ cd empty
bash-4.3$ echo *()
bash: syntax error near unexpected token `('
bash-4.3$ shopt -s extglob
bash-4.3$ echo *()

shell 在最后一个命令后挂起。请注意,我 运行 它在一个空目录中;非空目录也会出现此问题。

bash 手册记录了一种仅在启用 extglob 时才启用的通配符形式:

`*(PATTERN-LIST)'
     Matches zero or more occurrences of the given patterns.

鉴于 *(),空字符串出现零次或多次。由于在任何字符串中都会出现无限多次空字符串,如果没有特殊情况代码来避免它,我可以看到这将如何导致无限循环。

并且它似乎已在更高版本中修复。我在 4.3.11 中看到了问题,但在 4.3.30 中没有看到。 rici 的评论表明补丁 016 可能已修复它。而补丁对应的bug report包括这个:

1) bash gets stuck

shopt -s extglob
echo !(*/) # never returns, cannot be interrupted

我想说的是确认这是错误。