【发布时间】:2012-07-12 11:21:03
【问题描述】:
编译后的命令行程序有什么方法可以告诉 bash 或 csh 它不希望在其参数中扩展任何通配符?
例如,可能需要一个 shell 命令,例如:
foo *
简单地返回该字符的数字 ASCII 值。
【问题讨论】:
编译后的命令行程序有什么方法可以告诉 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
【讨论】:
pwd,echo * 只是*
nullglob 被禁用,则单词保持不变。如果设置了 nullglob 选项,但没有找到匹配项,则删除该单词。"
set -f ?是unset -f吗?
set +f
虽然命令本身确实不能关闭通配,但用户可以告诉 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 shell:
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 shell:
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 "*"
【讨论】:
set -o noglob 禁用通配符扩展。
注意:如果没有与掩码匹配的名称,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']
【讨论】:
set -o nullglob 或 shopt -s failglob,这种行为将会改变(以两种截然不同的方式)。