Stop shell wildcard character expansion?

后端 未结 4 1510
Happy的楠姐
Happy的楠姐 2020-11-22 11:05

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?

For instance, one

相关标签:
4条回答
  • 2020-11-22 11:10

    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.

       set -o noglob
    

    will switch off expansion in the invoking shell, but you'd have to do that before you invoke your program.

    The alternative is to quote your arguments e.g.

    foo "*"
    
    0 讨论(0)
  • 2020-11-22 11:10

    Beware: if there are no names matching the mask, bash passes the argument as-is, without expansion!

    Proof (pa.py is a very simple script, which just prints its arguments):

     $ ls
    f1.cc  f2.cc  pa.py
     $ ./pa.py *.cc
    ['./pa.py', 'f1.cc', 'f2.cc']
     $ ./pa.py *.cpp
    ['./pa.py', '*.cpp']
    
    0 讨论(0)
  • 2020-11-22 11:11

    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:

    For the sh, bash and ksh shells:

    alias foo='set -f;foo';foo(){ command foo "$@";set +f;}
    

    For the csh and tcsh shells:

    alias foo 'set noglob;\foo \!*;unset noglob'
    

    For the zsh shell:

    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:

    For the sh, bash and ksh shells:

    alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
    

    For the csh and tcsh shells:

    alias foo 'set noglob;$home/bin/foo \!*;unset noglob'
    

    For the zsh shell:

    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.

    Update:

    User geira has pointed out that in the case of a bash shell

    alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
    

    could be replaced with

    reset_expansion(){ CMD="$1";shift;$CMD "$@";set +f;}
    alias foo='set -f;reset_expansion ~/bin/foo'
    

    which eliminates the need for the function foo.

    Some web sites used to create this document:

    • Unix shell

    • Pass Command Line Arguments To a Bash Alias Command

    • Csh - The C Shell

    • Bash Builtin Commands

    • Comparison with the Bourne shell and csh startup sequences

    • Alias Loop in csh

    • How to pass command line arguments to a shell alias?

    • Invoking program when a bash function has the same name

    • Special shell variables

    • C Shell Aliases with Command-Line Arguments

    • Preventing Wildcard Expansion / Globbing in Shell Scripts

    0 讨论(0)
  • 2020-11-22 11:24

    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.

    $ # 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
    
    0 讨论(0)
提交回复
热议问题