Title: Extended globbing inside script - what am I doing wrong?
Tags: bash;scripting;wildcards;shopt
Question: so I'm trying to select a range of files using an interactive script.

The end goal is to use the ```read``` command but for demonstration here I assigned the ```glob``` variable manually

```#!/bin/bash
shopt -s extglob
# read -rp "Please enter a globbing string:"$'\n' glob

# This will give me an error (See below)
glob=*2020_04_03_{06..18}.jpg
/bin/ls -la /mnt/drive1/images/*/*/${glob}

# While this will return the desired files
/bin/ls -la /mnt/drive1/images/*/*/*2020_04_03_{06..18}.jpg
```

The error is as follows:

```Error /bin/ls: cannot access "/mnt/drive1/images/*/*/*2020_04_03_{06..18}.jpg": No such file or directory
```

So what am I missing here in either assigning the ```glob``` variable or appending the ```glob``` variable to my path?

Solution:

I found a solution but I'm not quite sure why but

```bash <<EOF
/bin/ls -la /mnt/drive1/images/*/*/${glob} 
EOF
```

will give me the desired output.

Comment: Think about this for a bit. What value are you hoping that your `$glob` variable should contain? And what happens if that value is appended to a path? When should the brace expansion be done (when assigning to `glob` or in the call to `ls`)? Brace expansions are, by the way, done before variable expansions, so you can't expect a brace expansion inside a variable's value to do anything.

Comment: Your script does not contain any extended globbing pattern, so `shopt -s extglob` is not needed.

Comment: You could do that with `eval`, but then you will be in worse trouble if a user inputs a string such as `; rm -rf *` (removes files) or `/*/*/*/*/../../../../*/*/*/*` (may act like a denial-of-service attack). I may look for a solution to this question during the upcoming week if nobody else gives a good answer.

Comment: What's the _intention_ with your code? Are you going to use the generated output from `ls` for anything? Is the purpose of getting the user to input a pattern to make it easier for the user to generate the `ls` output?

Comment: If you have a solution that works for you, you may want to add it as an answer rather than as part of the question. Self-answers are allowed. Unless you want to rephrase your question to be about what you ask in your edit.

Comment: Use an array instead of a variable.

Comment: @Kusalananda thank you for your comment, I've never thought about that. I think I want the brace expansion to happen with the call of ´ls´ so that the ´$glob´ variable only carries the string over to the path. Is there a way to do so, since you mentioned that brace expansion happens before variable expansion?

Comment: @Kusalananda So the use case for me is to pass a globbing string into the glob variable through the `ŕead` command. Then the `ls` output will be piped to `wc -l` to count the globbed files. After that I'll use the same `glob` variable to `convert` my .jpg files to a .gif. I'll be the only user of this script so security concerns as you mentioned above are not really an issue for me.


Here is another answer: You can use an array assignment instead of just a variable.

```shopt -s nullglob  ##: just in case there is non match for the glob.

glob=(*2020_04_03_{06..18}.jpg) ##: This will expand the glob * and brace expansion.

/bin/ls -la /mnt/drive1/images/*/*/"${glob[@]}"
```


That should work for your sample code.
The problem will come when you decided to replace the numbers inside the brace expansion with a variable which was mentioned by @kusalananda, about the sequence of expansion.
Add the ```failglob``` shell option if you want to see an error and exit with non-zero if there are none matching pattern.


Comment for this answer: It would be too early to expand the `*` glob in the array assignment, so quote the bits of the string that shouldn't be expanded, e.g. `glob=( '*2020_04_03_'{06..18}.jpg`.  You then get a list in `glob`. You may also want to take a look at what happens when you expand that list with the path prepended to it in the call to `ls` (it will _not_ prepend the path to each element). There, you additionally _don't_ want to quote the expansion, since you want it to act as a globbing pattern.
Comment for this answer: I will not answer the question because I don't really see a safe way of using a globbing pattern provided by the user. Sure, it's relatively easy to do, but since code written here tends to be picked up by more people than the person asking the question, I wouldn't want the _convenient_ solution to find its way into production systems.
Comment for this answer: @Kusalananda, ok, I will just wait for your answer so I can learn from this too.
Comment for this answer: @Jetchisel thank you for your answer. Unfortunately your example will select and return every file within `/mnt/drive1/images/*/*/`. I also tried the suggestion from Kusalananda  without success.

{'source': 'StackExchangeDataset', 'subset': 'unix.stackexchange.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 8, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2020:00:04/05/20', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<bash><scripting><wildcards><shopt>', 'Title': 'Extended globbing inside script - what am I doing wrong?', 'ViewCount': 449, 'id': 578133, 'user_AboutMe': None, 'user_AccountId': 12792490.0, 'user_DisplayName': 'Eike', 'user_Reputation': 29.0, 'user_Views': 0.0, 'user_id': 339794.0}}