停止shell通配符扩展?

hot*_*aw2 71 bash wildcard

有没有办法让编译的命令行程序告诉bash或csh它不希望扩展其参数中的任何通配符?

例如,可能需要一个shell命令,如:

foo *
Run Code Online (Sandbox Code Playgroud)

简单地返回该字符的数字ASCII值.

c00*_*ter 101

不会.扩展发生在命令实际运行之前.
您只能在运行命令之前禁用glob或引用星号.

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

$ # or disable the glob (noglob)
$ set -f
$ foo *

$ # alternative to set -f
$ set -o noglob
$ # undo it by 
$ set +o noglob
Run Code Online (Sandbox Code Playgroud)

  • @sam这实际上取决于您的选项设置方式.[来自tldp:](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html)"如果找不到匹配的文件名,并禁用shell选项`nullglob`,则单词为保持不变.如果设置了`nullglob`选项,并且未找到匹配项,则删除该单词." (6认同)
  • 另外,如果没有任何扩展,就没有扩张.即,使用空的`pwd`,`echo*`只是`*` (3认同)
  • @NamGVU`设置+f` (3认同)

Dav*_*son 51

虽然命令本身不能关闭通配符,但是用户可以告诉Unix shell不要对特定命令进行通配.这通常通过编辑shell的配置文件来完成.假设foo可以在命令路径中找到该命令,则需要将以下内容添加到相应的配置文件中:

对于sh,bash和ksh shell:

alias foo='set -f;foo';foo(){ command foo "$@";set +f;}
Run Code Online (Sandbox Code Playgroud)

对于csh和tcsh shell:

alias foo 'set noglob;\foo \!*;unset noglob'
Run Code Online (Sandbox Code Playgroud)

对于zsh shell:

alias foo='noglob foo'
Run Code Online (Sandbox Code Playgroud)

不必使用命令路径.假设命令foo存储在目录〜/ bin中,那么上面的内容将变为:

对于sh,bash和ksh shell:

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
Run Code Online (Sandbox Code Playgroud)

对于csh和tcsh shell:

alias foo 'set noglob;$home/bin/foo \!*;unset noglob'
Run Code Online (Sandbox Code Playgroud)

对于zsh shell:

alias foo='noglob ~/bin/foo'
Run Code Online (Sandbox Code Playgroud)

所有上述内容均使用Apple的OSX 10.9.2进行测试.注意:复制上述代码时,请注意删除任何空格.它们可能很重要.

更新:

用户geira指出,在bash shell的情况下

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
Run Code Online (Sandbox Code Playgroud)

可以替换为

reset_expansion(){ CMD="$1";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'
Run Code Online (Sandbox Code Playgroud)

这消除了对函数foo的需要.

用于创建此文档的一些网站:

  • 这应该是公认的答案,因为它证明确实可以做OP想要的事情.对于bash中的一些更好的方法,此链接记录了各种选项:http://blog.edwards-research.com/2011/05/preventing-globbing/ (2认同)

Bri*_*new 7

在程序运行之前,shell将执行扩展.您的程序不知道是否发生了扩展.

   set -o noglob
Run Code Online (Sandbox Code Playgroud)

将关闭调用shell中的扩展,但调用程序之前必须这样做.

另一种方法是引用你的论点,例如

foo "*"
Run Code Online (Sandbox Code Playgroud)

  • setopt似乎是特定于zsh的命令.正如另一张海报所说,对于bash,你使用`set -o noglob`来禁用通配符扩展. (4认同)