11

I'd like to be able to write * to my script, and to get * as-is (i.e., without expansion).

Bash will try to replace it with local files matching this pattern, and if this pattern doesn't exist, bash will pass the asterisk without modifications.

I don't want to escape. I know it's possible ( *, '*' ).

e.g.

myscript --arg *   --- will pass local files to the script
myscript --arg=*   --- will pass "--arg=*", since there are no filenames starting with "--arg=<...>"

Can I tell bash to skip wildcard interpretation on certain occasions? e.g. with commands starting with myscript?

Berry Tsakala
  • 292
  • 5
  • 14

2 Answers2

21

Yes. You can use set -f:

set -f
echo *  # prints *
# turn glob expansion back on, if you want:
set +f

If you choose this route, you'll have to set it in the terminal where you're calling your script, not in your script itself, as the * expands before reaching your script as an argument.

As mentioned in the comments, it's probably better to just escape the *, either via '*', "*", or \*.

1
$ cat myscript
for a ;do echo "-$a-"; done
exit 7

$ cat setup
myscript_helper() { set +o noglob; ./myscript "$@"; }
alias myscript='set -o noglob; myscript_helper'

$ source setup

$ myscript *; echo $? *
-*-
7 myscript setup

myscript is your external script. Here it just echos its arguments and exits with an exit status of 7. setup is the script to create a helper function and an alias; it must be sourced (dotted) to add the function and alias to your current shell.

When you run myscript, the alias is called and set -o noglob (same as set -f) runs before the arguments are parsed and passed to myscript_helper. When the function myscript_helper runs (in the current shell), it first resets noglob before calling the script myscript with the specified arguments and returning the exit status (7 in this case).

This hack should be used for interactive use only. The results might be very surprising in this particular use-case, but the general technique can be used in a variety of situations. For example, I use this method to call (at the command line) a script xyz which needs to be sourced, but the alias xyz takes care of sourceing the script xyz for me.

jrw32982
  • 158