8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

停止 shell 通配符扩展?

riffnl 2月前

107 0

编译后的命令行程序是否有办法告诉 bash 或 csh,它不希望在其参数中扩展任何通配符?例如,可能需要像这样的 shell 命令...

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

例如,可能需要如下 shell 命令:

foo *

仅返回该字符的数字 ASCII 值。

帖子版权声明 1、本帖标题:停止 shell 通配符扩展?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由riffnl在本站《bash》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 不。扩展发生在命令实际运行之前。
    您只能在运行命令之前或通过引用星号来禁用 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 * 只是 *

  • @sam 这实际上取决于您的选项设置方式。来自 tldp: \'如果没有找到匹配的文件名,并且 shell 选项 nullglob 被禁用,则该词保持不变。如果设置了 nullglob 选项,并且没有找到匹配项,则删除该词。\'

  • @c00kiemon5ter 如何撤消 set -f ?是 unset -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 的需要。

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

    • p13

    • p14

    • 第15页

    • p16

    • p17

    • p18

    • 第19页

    • p20

    • p21

    • 第22页

    • p23

  • 这应该是可接受的答案,因为它证明了确实可以实现 OP 想要的结果。对于 bash 中的一些更好的方法,此链接记录了各种选项:blog.edwards-research.com/2011/05/preventing-globbing

  • @geira:有时,在发布更好的答案之前,答案就被接受了。我相信这可能是其中一种情况。我还相信,被用户标记为最有用的答案最终会排在第一位。注意:我将您的意见添加到了我的答案中。

  • Ely 2月前 0 只看Ta
    引用 9

    @geira,OP 希望编译后的程序能够与 shell 进行通信;回答说可以根据每个命令配置 shell 以按照需要运行是一个有用的答案,我自己也会接受这个答案,但我确实看到对于它是否完全正确存在不同意见。

  • NBur 2月前 0 只看Ta
    引用 10

    可以做到并不意味着应该这样做。让 shell 的行为偏离用户对 select 命令的合理期望听起来很令人惊讶,而且最终是不可取的。

  • 引用 11

    @tripleee:曾经有一段时间,人们期待继电器和真空管。人们期待的是打孔的纸板和纸带。人们拿着计算尺而不是计算器和电话。我想这对你来说是理想的。我不太在意那个时代。我确实喜欢看到接下来会发生什么。

  • 扩展是在程序运行之前由 shell 执行的。程序不知道扩展是否已经发生。

       set -o noglob
    

    将关闭调用 shell 中的扩展,但是您必须 调用程序 之前

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

    foo "*"
    
  • setopt 似乎是 zsh 特有的命令。正如另一位发帖者所说,对于 bash,您可以使用 set -o noglob 来禁用通配符扩展。

  • 引用 14

    哦天哪,谢谢你!我需要在通过可能包含 cron 样式字符串的数组变量连接字符串时抑制通配符扩展(例如 \'10 * * * *\')——花了好长时间才解决这个问题——set -o noglob 成功了!!

  • 引用 15

    注意:如果没有与掩码匹配的名称,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']
    
  • Gen 2月前 0 只看Ta
    引用 16

    并非总是如此。set -o nullglob 或 shopt -s failglob,这种行为就会改变(以两种非常不同的方式)。

返回
作者最近主题: