bash 停止shell通配符扩展?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11456403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stop shell wildcard character expansion?
提问by hotpaw2
Is there any way for a compiled command-line program to tell bash or csh that it does not want any wildcard characters in its parameters expanded?
编译后的命令行程序有什么方法可以告诉 bash 或 csh 它不希望在其参数中扩展任何通配符?
For instance, one might want a shell command like:
例如,人们可能想要一个 shell 命令,如:
foo *
to simply return the numeric ASCII value of that character.
简单地返回该字符的数字 ASCII 值。
回答by c00kiemon5ter
No. The expansion takes place before the command is actually run.
You can only disable the glob before running the command or by quoting the star.
不会。扩展发生在命令实际运行之前。
您只能在运行命令之前或通过引用星号来禁用 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
回答by David Anderson
While it is true a command itself can not turn off globbing, it is possible for a user to tell a Unix shell not to glob a particular command. This is usually accomplished by editing a shell's configuration files. Assuming the command foo
can be found along the command path, the following would need to be added to the appropriate configuration file:
虽然命令本身确实不能关闭 globbing,但用户可以告诉 Unix shell 不要 glob 特定命令。这通常是通过编辑 shell 的配置文件来完成的。假设foo
可以在命令路径中找到该命令,则需要将以下内容添加到相应的配置文件中:
For the sh, bash and ksh shells:
对于 sh、bash 和 ksh 外壳:
alias foo='set -f;foo';foo(){ command foo "$@";set +f;}
For the csh and tcsh shells:
对于 csh 和 tcsh shell:
alias foo 'set noglob;\foo \!*;unset noglob'
For the zsh shell:
对于 zsh 外壳:
alias foo='noglob foo'
The command path does not have to be used. Say the command foo is stored in the directory ~/bin, then the above would become:
不必使用命令路径。假设命令 foo 存储在目录 ~/bin 中,则上述内容将变为:
For the sh, bash and ksh shells:
对于 sh、bash 和 ksh 外壳:
alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
For the csh and tcsh shells:
对于 csh 和 tcsh shell:
alias foo 'set noglob;$home/bin/foo \!*;unset noglob'
For the zsh shell:
对于 zsh 外壳:
alias foo='noglob ~/bin/foo'
All of the above was tested using Apple's OSX 10.9.2. Note: When copying the above code, be careful about deleting any spaces. They may be significant.
以上所有内容均使用 Apple 的 OSX 10.9.2 进行测试。注意:复制上述代码时,请注意删除任何空格。它们可能很重要。
Update:
更新:
User geirahas pointed out that in the case of a bash shell
用户geira指出,在 bash shell 的情况下
alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
could be replaced with
可以替换为
reset_expansion(){ CMD="";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'
which eliminates the need for the function foo.
这消除了对函数 foo 的需要。
Some web sites used to create this document:
一些用于创建此文档的网站:
回答by Brian Agnew
The expansion is performed by the shell before your program is run. Your program has no clue as to whether expansion has occurred or not.
在你的程序运行之前,扩展是由 shell 执行的。您的程序不知道是否发生了扩展。
set -o noglob
will switch off expansion in the invoking shell, but you'd have to do that beforeyou invoke your program.
将关闭调用 shell 中的扩展,但您必须在调用程序之前执行此操作。
The alternative is to quote your arguments e.g.
另一种方法是引用您的论点,例如
foo "*"
回答by lesnik
Beware: if there are no names matching the mask, bash passes the argument as-is, without expansion!
注意:如果没有与掩码匹配的名称,bash 将按原样传递参数,不进行扩展!
Proof (pa.py is a very simple script, which just prints its arguments):
证明(pa.py 是一个非常简单的脚本,它只打印其参数):
$ ls
f1.cc f2.cc pa.py
$ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
$ ./pa.py *.cpp
['./pa.py', '*.cpp']