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 might want a shell command like:
foo *
to simply return the numeric ASCII value of that character.
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 *
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
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 \"*\"
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\']
No. A Bourne-style shell always performs globbing when appropriate before executing the command. The user has to quote or escape the arguments to prevent globbing, like foo \\*
; the actual program being executed cannot indicate a preference.