2

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.

8
  • 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.
    – Kusalananda
    Apr 5 '20 at 19:22
  • Your script does not contain any extended globbing pattern, so shopt -s extglob is not needed.
    – Kusalananda
    Apr 5 '20 at 19:23
  • @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?
    – Eike
    Apr 5 '20 at 19:50
  • 2
    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.
    – Kusalananda
    Apr 5 '20 at 20:02
  • Use an array instead of a variable.
    – Jetchisel
    Apr 6 '20 at 0:28
1

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.

4
  • 1
    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.
    – Kusalananda
    Apr 6 '20 at 5:42
  • @Kusalananda, ok, I will just wait for your answer so I can learn from this too.
    – Jetchisel
    Apr 6 '20 at 5:55
  • @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.
    – Eike
    Apr 6 '20 at 16:01
  • 1
    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.
    – Kusalananda
    Apr 9 '20 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.