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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:24:53  来源:igfitidea点击:

Stop shell wildcard character expansion?

bashwildcard

提问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 foocan 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']