编译后的命令行程序有什么方法可以告诉 bash 或 csh 它不希望扩展其参数中的任何通配符?
例如,可能需要一个 shell 命令,例如:
foo *
简单地返回该字符的数字 ASCII 值。
不会。扩展发生在命令实际运行之前。
您只能在运行命令之前或通过引用星号来禁用 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
虽然命令本身确实不能关闭通配,但用户可以告诉 Unix shell 不要通配特定命令。这通常通过编辑 shell 的配置文件来完成。假设foo
可以在命令路径中找到该命令,则需要将以下内容添加到相应的配置文件中:
对于 sh、bash 和 ksh shell:
alias foo='set -f;foo';foo(){ command foo "$@";set +f;}
对于 csh 和 tcsh shell:
alias foo 'set noglob;\foo \!*;unset noglob'
对于 zsh 外壳:
alias foo='noglob foo'
不必使用命令路径。假设命令 foo 存储在目录 ~/bin 中,那么上面的内容将变为:
对于 sh、bash 和 ksh shell:
alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
对于 csh 和 tcsh shell:
alias foo 'set noglob;$home/bin/foo \!*;unset noglob'
对于 zsh 外壳:
alias foo='noglob ~/bin/foo'
以上所有内容均使用 Apple 的 OSX 10.9.2 进行了测试。注意:复制上述代码时,请注意删除任何空格。它们可能很重要。
用户geira指出,在 bash shell 的情况下
alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
可以替换为
reset_expansion(){ CMD="$1";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'
这消除了对函数 foo 的需要。
用于创建此文档的一些网站:
扩展是在程序运行之前由 shell 执行的。您的程序不知道是否发生了扩展。
set -o noglob
将关闭调用 shell 中的扩展,但您必须在调用程序之前执行此操作。
另一种方法是引用您的论点,例如
foo "*"
注意:如果没有匹配掩码的名称,bash 会按原样传递参数,而不进行扩展!
证明(pa.py 是一个非常简单的脚本,它只打印它的参数):
$ ls
f1.cc f2.cc pa.py
$ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
$ ./pa.py *.cpp
['./pa.py', '*.cpp']