10

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?

3
  • 4
    Escape it :) See askubuntu.com/questions/681637/…
    – Rinzwind
    Dec 18, 2020 at 13:22
  • @Rinzwind "as is", meaning: without escaping (I edited my question). I'm aware of escaping. Dec 19, 2020 at 13:27
  • Dont forget to escape the escape character on stackexchange ;)
    – Andreas
    Dec 19, 2020 at 14:03

2 Answers 2

20

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 \*.

4
  • Nice. thanks. I should've (of course) clarify my questions - i'm looking for a per-app settings, or otherwise a way to simplify input; I can't use it in a script and I can't use an alias (because it requires a set +f after the actual command. Dec 26, 2020 at 0:49
  • Escaping doesn't always work. For example a(){ arr=($(echo "$1" | sed "…")); echo "$arr";}; a \* outputs the first file name instead of "*". Except in an empty folder, only there it works as expected. For a minute I considered horrible workarounds with temporary empty folders, until I decided to look for a way to temporarily disable that feature, which is of course way less insane. Feb 20, 2022 at 20:58
  • @FabianRöling, escaping is working in your example - a receives * as its only argument. The fact that a can do anything it wants with that * is beyond the scope of OP's question. Feb 20, 2022 at 22:17
  • I meant inside the function. I found no other way to keep the asterisk inside the function, except for quoting the entire $() block, which makes it one big string in the array instead of multiple separate ones. (The sed command introduces newlines, in case that matters.) Another advantage is also that you don't need to worry anymore about this problem in the entire rest of the script. Feb 21, 2022 at 3:01
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.

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .